一、简介
1~2亿条数据需要缓存,请问如何设计这个存储案例,单机单台100%不可能,肯定是分布式存储,用redis如何落地?
分布式存储算法-哈希取余分区
优点:简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求,起到负载均衡+分而治之的作用。
缺点:当原来规划好的节点 ,进行扩容或缩容(或者某节点故障),导致节点数发生了变化,此时,映射关系需要重新计算 ,根据元老公式获取的服务器将会变得不可控。
分布式存储算法-一致性哈希算法
问题:解决分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了;
目的:当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系;
步骤:
算法构建一致性哈希环
一致性哈希算法必然有个hash函数并按照算法产生哈希值。这个算法的所有可能哈希值会构成一个全量集,这个集合可以成为一个hash空间[0,2^32-1],这是一个线性空间,我们通过适当的逻辑控制将它首尾相连(0=2^32),这样让它逻辑上形成一个环形空间。
它也是按照使用取模的方法,一致性哈希算法是对2^32取模,简单来说,一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环。
服务器IP节点映射
将集群中各个IP节点映射到环上的某一个位置
将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,这样每台机器就能确定其在哈希环上的位置。
key落到服务器的落剑规则
当我们需要存储一个kv键值对时,首先计算key的hash值,hash(key),将这个key使用相同的函数Hash计算出哈希值并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储在该节点上。
优点:容错性和拓展性
加入和删除节点只影响哈希环中顺时针方向的相邻节点,对其他节点无影响。
缺点:数据倾斜
数据的分布和节点位置有关,因为这些节点不是均匀的分布在哈希环上的,所以数据在进行存储时达不到均匀分布的效果。
分布式存储算法-哈希槽分区
在数据和节点之间又加了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系。一个集群只能有16384个插槽,这些槽会分配给集群中的所有主节点,分配策略没有要求,可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。然后使用CRC16(key)%16384计算槽位。