感叹自己拿来这么大的激情呀,前段时间对分布式的raft感兴趣,这两天又着迷于golang。 听起来是不是有装逼的成分? 勿喷 …
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。
今天一直在封闭式开发,针对电商接入SuperSpide适配兼容性进行调整。 中间跟同事杨博探讨了一个问题,原由是因为我们现在的服务对于redis特别的依赖,所以从单机的redis迁入到redis cluster集群中。
这redis集群属于基础组件,很多项目都在使用者集群,如果不进行合理的约束很好可能造成key的重复覆盖。
那么如何不让这些key重复?
我们可以这样操作,在每个key前面加入前缀。 伪代码: redis_client.set(key + prefix_str, value)
但是这有一个问题,你要把你用的那些redis命令都封装一下? 这是个方法,但其实有更漂亮的实现方式,就是利用python的魔法函数、自省模式解决这类问题。
#http://xiaorui.cc import redis class MessageQueue(object): def __init__(self, host, port): self._conn = redis.Redis(connection_pool=redis.BlockingConnectionPool(max_connections=15, host=’127.0.0.1', port=6379) self.keystr = "id:xiaorui.cc:" def __getattr__(self, command): def _(*args, **kwds): args = list(args) args[0] = self.keystr+args[0] print args,command return getattr(self._conn,command)(*args) return _ def __call__(self, command, *args, **kwds): print 'end' MQ = MessageQueue() MQ.set('nima','http://xiaorui.cc')
只要理解了python的那几个魔法函数( __getattr__ 、__call__),就可以明白上面的python代码了。
1. 当访问不存在的函数时会访问__getattr__ ,他就好像是一个异常处理函数.
2. 每次通过实例访问属性时,都会经过__getattribute__函数。而当属性不存在时,仍然会触发__getattribute__函数.
我们可以基于这方式实现一致性哈希负载均衡。现在市面上比较出名的redis一致性hash代理是redis twemproxy,但对于redis client来说多了一层的proxy,相当于多了两次网络io消耗。
说实话我不是很喜欢这样的运作方式,更倾向于把一致性哈希放到客户端搞,像redis cluster client那样自己做路由选择,另外还会缓存cache key与主机的关系。
暂时没有时间,等过段时间把代码整理下放到github上。http://github.com/rfyiamcool