Redis Cluster 初探(2) - 运行规制

上一篇文章我们说过,Redis Cluster 采用Smart Client的方式,避免与节点的通讯还需要通过一层Proxy,以达到性能地提升。 Smart Client的优点与缺点网上也有很多人在讨论,我们现在来了解下Redis Client的连接模式。

Redis Cluster是无中心节点的设计,Client可以连接集群中的任一一个节点,当操作的Key不在该节点的Slot中的时候,如访问在Slot-6433的Key,客户端会返回一个 (error) MOVED 6433 10.211.55.4:7001 这样的错误信息。Client捕获到此异常后,再自动重定向到 10.211.55.4:7001 这个节点上并获取数据。

Slot Model

虽然每次请求客户端都会重新定向,但这样额外耗费多一次连接是很没有必要的,官方建议在初次建立连接后,Redis Client会获取连接集群的节点信息以及Slot分布信息,并在本地缓存一份hash slot与node关系的的路由表,当收到操作请求时,先本地用CRC16算法计算出该Key对应哪一个Slot,再在表中查询该Slot的节点信息,最后选择对应的节点去连接,这样,每次请求就不需要通过一个统一的代理层去转发请求。当服务器进行扩容,迁移数据的时候,客户端的路由表并不会立即更新,而是当在被迁移是Slot上操作的时候,因为Slot已经不在原先的节点上了,Redis Cluster返回Moved指令,告诉客户端该Slot现在所在的节点。此时,客户端应该更新自己的路由表信息,以达到最优,即每次操作直接与节点通讯并不进行跳转。


Smart Client Model

在前面我说道过,Redis Cluster预先将Key分到16384个Slot,通过CRC16算法算出Key该被分配到哪一个Slot中。

HASH_SLOT = CRC16(key) mod 16384 

但是这么做有一个缺陷就是,如果你需要进行涉及多个key的操作的话,因为Key可能被分散到不同的节点中,所以查询请求将会在各个节点间跳转,效率会非常差,为此,Redis Cluster干脆不支持所有的多Key操作命令。
假如你想使用多Key操作命令,可以通过Keys Hash Tag去将相关数据强制存储在同一个slot。当一个key包含{}的时候,Redis-Cluster会取{}之间的字符进行CRC16哈希算出存放在哪个slot,比如:

  • {user1000}.following这个key会使用user1000的hash值
  • foo{}{bar}这个key会使用foo{}{bar}的hash值,因为第一个{}之间的值为空
  • foo{{bar}}zap这个key会使用{bar的hash值
  • foo{bar}{zap}这个key会使用{bar}的hash值

但是使用Hash Tag仍然仍然会面临新的问题,因为不可避免会有些Key的Value额外的大,虽然根据概率学,当基数足够大的时候,每一个Slot的大小都会趋于平均,但实际应用中,我使用我们生产环境的一些数据进行测试,Cluster节点数目为16,测试数据集大概16G,存储数据结构为Set,每一个Key对应一个或多个Value,正常来说最终测试结果每一个节点的内存占用应该为1G,但实际上,内存使用最高与最低相差足足有200M。

在集群运行的过程中,不可避免有些节点会因为各种原因挂掉(被踢掉网线,打雷,停电,软件故障>_>)。所以,在成本允许范围内,我们会尽量避免所有节点在同一台物理机上,避免Master,Slave在同一台物理机上,利用Redis Cluster的自动故障转移的功能,让集群在及时部分节点挂掉的情况下,仍然能继续工作。

为了数据的安全性,我们一般会保持一份及以上的数据冗余。即一个Master节点对应多个Slave节点模式,当Master节点挂掉后,集群自动选择一个Slave升级为Master节点,重启原Master节点并作为Slave节点加入现有集群。

而Redis Cluster是如何发现节点挂掉呢?在集群中,每一个节点之间都会保持一个长连接,即有N个节点的集群,每个节点将会保持N-1条长连接,节点定时给其他节点发送Ping指定,如果在指定的timeout内没有返回Pong,即认为该节点故障,并启动故障转移。节点timeout的时间是可以配置,但是需要明白的是,当一个节点故障的时候,他通常不能写入数据并且不能读取数据,所以节点故障到其他节点发现其故障并且进行故障转移这段时间内,写入该节点的数据可能会丢失。所以timeout时间过长意味着你将在节点故障的时候丢书过多的数据,而timeout时间过短则可能引发误判。

当一个Master节点以及他的所有Slave节点都挂掉的时候,集群将处于不可用的状态,当然这是可以配置的。我们可以根据业务来决定是否打开此开关。

Redis在实际应用中的一些需要避免的一些坑,在Redis Cluster之中同样存在,在调研Redis Cluster与我实际测试中,总结一些别人遇到以及我自己掉入的坑。

  • 为什么Redis需要预留额外一半的内存?因为Redis的AOF实际上是通过fork一个Redis进程来实现,所以为了防止AOF集中发生,出现SWAP和OOM,所以需要预留额外的一半内存。但实际有更优的解决办法:

    1. 关闭Redis所有自动落地,通过一个Remote控制中心来管理Redis实例,远程调用BGSAVE命令主动触发落地。避免同一时间落地导致内存不足。
    2. 设置最大内存使用,当内存超过此阀值的时候,写入将失败,但读取仍然是正常的,可以配置告警脚本。这能最大限度保证Redis进程不会因为内存过高而挂掉。
  • 在云风的 谈谈陌陌争霸在数据库方面踩过的坑( Redis 篇) 中提到一个Redis的主从方案,即一个Master节点对应N个Slave节点,如果所有的节点都选择数据落地,每一台机器都需要预留很多内存来防止落地的时候的内存占用过高问题,但实际上这是很没有必要的,我们可以选择其中几个Slave节点进行数据落地即可。但这招在Redis Cluster是行不通的,因为Redis Cluster的故障迁移功能,默认是Master节点如果挂掉的话,Slave会自动升级为Master节点,原先的Master节点自动重启并作为Slave节点加入集群。这样如果我们在集群中指定其中几个Slave节点进行数据落地的话,当发生故障转移的时候,落地策略就会出现混乱。

参考文章

本文首发: http://xiezefan.me/2015/12/13/redis_cluster_research_2/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容