转:redis实践经验分享

为了保证查询的速度,他们用redis来保存用户数据的索引信息,下面是它们使用redis的方式及扩展方法:


1、一共是16台redis数据服务器,每台服务器是96G内存,这样一共是1.3T的内存容量


2、每台服务器有16个核,每台机器上运行了160个redis实例(因为一个redis实例最多只能占用一个核,所以需要跑多个实例来充分利用机器的资源)


3、同一份数据会复制到另外两台机器上,采用redis自带的数据复制机制对数据进行复制。写到主redis实例上,轮询读取写实例和另外两个读实例


4、另外有几台机器上面也运行redis实例,以保存实例IP地址、实例端口、负责的数据位置、健康状态信息。它们管这个叫目录服务。也是采用redis的数据复制机制复制目录信息到多个目录redis实例上。


5、目录服务大部分是读取,修改的情况比较少,所以读写比例非常高。应用程序采取轮询的方式轮流访问主目录实例和多个辅目录实例


6、当应用程序发现一个实例没有响应,它会去修改该实例对应的目录信息,将健康状态标专为离线,这样别的应用和实例都不会再去访问出问题的实例


7、当数据分片对应的辅redis实例出错离线时,该分片对应的数据仍然能够正常读取,只是冗余性下降了


8、当数据分片对应的主redis实例出错离线时,该分片对应的数据只能提供读取服务,数据不能再被修改


9、运行了一个特殊的代理进程,它不断查询目录节点,当发现有一个分片的主redis实例离线时,由它来推动从剩下的辅redis实例中选举一个做新的主redis实例,并配置别的实例是它的辅redis实例,然后再清掉分片对应的目录信息,从只读模式中恢复成读写模式。这个过程还没有做到完全的自动化,他们有计划做到完全自动地恢复

 

10、所有redis数据服务器用单独的网卡接到专用的网络中,里面有网络存储,这样所有redis实例会定时将数据快照存到网络存储上

 

11、因为redis保存数据快照需要额外的内存,具体数据跟写的比例和io速度有关系,这样如果一台redis数据服务器上的所有实例同时都写快照,这样会因内存的占用而影响服务。为了避免这个问题,他们的作法是在每台redis数据服务器运行一个单独的进程,轮流访问上面的每个实例,调用save命令来保存快照


12、采用一致性哈希算法按用户邮件名,将用户索引数据分片到对应的redis实例上。具体是用sha1算法将邮箱名64位无符号整数空间内按实例数平均分配64位空间,每个实例占用相同的区间大小。用sha1计算用户邮箱对应的数值,按顺时针方面寻找最近的实例,由该实例负责对应的用户

image

image

13、他们对比多个哈希函数,最后选定sha1,因为它能均匀分布用户到多个redis实例上

 
14、当增加新的实例时,它会占据在两个实例的中间位置。但不是从老的实例中搬移数据到新的节点上。当一个实例没有对应的数据时,会按顺时针方向转发请求到下一个实例

image

15、当一个实例内存已经用满,它也会按顺时针方向转发请求给下一个实例

image

16、在应用端会缓存用户对应的实例信息,这样避免每次都进行上面的定位和转发步骤


17、没有使用libredis(采用了ketama)原因是自己写的方式比较好一步一步地跟踪,同时能解决redis环境下的特定的问题

 

18、一致性哈希采用C++实现,另外用了一些tcl脚本。开源了Redis C++客户端库, 计划把一致性哈希实现也发到这个开源客户端中

posted @ 2012-10-12 14:57  简单-陈勇  阅读(244)  评论(0编辑  收藏  举报