我要开始吐槽了,这两天让公司的Hbase搞的高潮四起,有一个namenode的节点,总是出问题,他的一些个问题,引起其他节点的性能的下降,反正很坑。 以前貌似没这个问题,还好我们组有个百度做底层的大拿,兵强。 这段时间估计会调整架构,调优啥的。
需要说明的是,爬虫太可耻了,虽然哥也是专业爬虫选手,原文链接是 http://xiaorui.cc
那么还有一个很牛逼的样子,我估计很多的朋友也遇到这样的问题,那就是Thrift的问题,这东西真心不靠谱呀,有时候还需要时不时的重启下,他作为一个RPC server的服务端,本身性能是强大的,只是他有段时间没更新了,有时候经常会遇到一些个堵塞的问题。甚至是挂掉等等。 我们这边有个extractor的逻辑,是抽取网页的信息,进行入库。 逻辑是很简单的,就是put信息。 但是因为和别的组公用几个thrift,搞得我们在hbase的插入堵塞,引起后面的逻辑,整个都堵塞了。
那么现在的解决的办法是,开多个Thrift接口,然后在我们自己的应用上做个轮训,但是问题来了,这段时间,因为要做50台mongodb的下线,数据要从hbase重新构造原始数据,这就需要大量的scan和读写了,然后又是年底,有大量的hbase的回溯任务,又尼玛有个namenode节点,出了两次事故,导致心理上总觉得慢。
那么问题是,这么多的任务量,会造成堵塞 ! 有人说,是不是你们hbase性能不行,经过我们的反复排除,hbase是没有问题的,压力是在thrift身上。 那么对于上层的应用来说,我如何的得到一个可用性的列表。 没有LVS和haproxy….. 自己做个proxy,又麻烦。 就直接在程序里面做了。
我这里用的是zookeeper,对于zookeeper,我还是有些好感的,记得以前在人人的时候,做自动化装机平台,有些逻辑是需要做分布式锁,来引导流程的一致性。虽然,后来我自己用memcached实现了个简单的,但是最少针对zookeeper入了个很小的门。那这次又记得起他是因为公司最近不少人采用zk做分布式的协调方案。 那么,我怎么用他? 很简单,连接zk后,我作为客户端,可以把自己节点的thrift信息,也就是 提供是否堵塞的信息,注册并更新到zookeeper里。 那么我应用的服务端启动的时候,也会注册到zk里面,并关联了watch监听,只要有反应,根据判断,我会从thrift队列里面干掉那些挂掉的节点以及被堵塞掉的thrift服务 。
### import pykeeper ### pykeeper.install_log_stream() # 创建zk连接 ### client = pykeeper.ZooKeeper('132.56.78.40:22181') ### client.connect() ### client.get_children('/') ['zookeeper'] # 创建node ### client.create_recursive('/buzzthrift/thrift_11', '{"ok": true}') ### client.create_recursive('/buzzthrift/thrift_15', '{"ok": true}') ### client.create_recursive('/buzzthrift/thrift_16', '{"ok": true}') ### client.create_recursive('/buzzthrift/thrift_19', '{"ok": true}') ### client.get_children('/') ['buzzthrift', 'zookeeper'] ### bool(client.exists('/buzzthrift')) True #node的信息 ### client.get_children('/buzzthrift') ['thrift_11','thrift_15','thrift_16','thrift_19'] ### client.get('/buzzthrift/thrift_11') ('{"ok": true}', {'pzxid': 3620L, 'ctime': 1328717487776L, 'aversion': 0, 'mzxid': 3620L, 'numChildren': 0, 'ephemeralOwner': 0L, 'version': 0, 'dataLength': 12, 'mtime': 1328717487776L, 'cversion': 0, 'czxid': 3620L})
需要说明的一点是,python针对zookeeper的操作模块,还是选用kazoo吧,因为他是纯python构造的,文档也相对的丰富,你如果想改,也相对容易。
我这里用了一个zookeeper一个监听回调的东西,那就是watchers 。就拿我上面的例子来说,在30台hbase里面,开启了15个Thrift Server ,我不能很不时尚的,总是get_children的node信息。 我只是需要做watchers就行了。
def my_func(event): # check to see what the children are now # Call my_func when the children change children = zk.get_children("/my/favorite/node", watch=my_func)
Kazoo 官方还配备了kazoo的异步模块,可以做一些网络io的异步。
import sys from kazoo.exceptions import ConnectionLossException from kazoo.exceptions import NoAuthException def my_callback(async_obj): try: children = async_obj.get() do_something(children) except (ConnectionLossException, NoAuthException): sys.exit(1) # Both these statements return immediately, the second sets a callback # that will be run when get_children_async has its return value async_obj = zk.get_children_async("/some/node") async_obj.rawlink(my_callback)
其实这次写了不少代码,但是核心的就那些东西,写的更多的是关于业务逻辑的。 大家多看看zookeeper的原理性质的东西,zookeeper在一些分布式架构中使用还是很广泛的 。
多写点zookeeper的文档