docker学习(九、分布式存储亿级数据知识)
- 一、哈希取余分区
- 二、一致性哈希算法分区
- 三、哈希槽分区(重点)
内容整体是以Redis做分布式为例的~~~先出理论,后出实践docker操作
一、哈希取余分区
举个例子:目前有2亿条数据存储在Redis数据库中,使用分布式多台机器存储。
如果是3台机器构成的一个集群,用户每次读写都会根据公式hash(key)%N获取到要映射的机器位置。
优点:
简单粗暴,直接有效,只需要预估好数据规划好节点即可。通过hash算法让固定的一部分请求落到同一台服务器上,这样就起到了负载均衡+分而治之的效果了。
缺点:
扩容或者缩减的时候,节点会有所变化,映射关系需要重新计算。取模公式N也会变化,导致数据需要重新洗牌。
二、一致性哈希算法分区
一致性哈希算法将整个哈希空间(通常是一个圆环)划分为多个虚拟节点,并将这些虚拟节点映射到物理节点上。每个物理节点负责一定范围内的哈希空间。
将所有的存储节点排列在首位相接的Hash换上,每个Key在计算Hash后会在哈希环上顺时针查找最近的虚拟节点存放。而当节点加入或退出时仅影响节点在Hash环上顺时针相邻最近的节点。
优点:
- 容错性:假设节点B宕机,可以看到此时只有B被重定向到C。如果一台服务器不可用,则受影响的数据仅仅是此服务器到其换空间中前一台服务器(逆时针最近的一台)之间数据,其他不会受影响。
- 扩展性:增加一个节点X,例如在AB之间,那受到影响的只有A到X之间的数据,重新把A到X的数据录入到X上即可,不会导致hash取余全部数据重新洗牌。
总结起来就是加入和删除节点只影响哈希环顺时针方向的相邻节点,对其他节点无影响。
缺点:
- Has环节点太少时,容易因为节点分布不均匀导致数据倾斜(被缓存的对象大部分集中在了某一台服务器上)问题。
数据的分布和节点位置有关,节点不均匀时,数据在进行存储时也可能达不到均匀分布的效果。
三、哈希槽分区(重点)
哈希槽实质是一个数组[0,
2
14
−
1
2^{14} -1
214−1]形成的hash slot空间。
作用:
解决均匀分配问题,在数据和节点之间又加了一层,把这个层叫做哈希槽(slot),用于管理数据和节点之间的关系,现在相当于节点上放的是槽,槽里放的是数据。
- 槽解决的是粒度问题,相当于把粒度变大,便于移动数据。
- 哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。
槽的个数:
一个集群只能有16384个槽,编号0~16383(0 ~
2
14
−
1
2^{14} -1
214−1)。
解决槽和节点的关系:
可以直接指定槽的编号分配给集群的某个主节点。
解决数据移动问题:
对key求哈希值,然后对16384取余,余数是几就落入对应的槽里。slot=CRC16(key)%16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样移动数据问题就解决了。