首先,可以很确定的是,单机单台承载不了这么多数据,采用分布式存储。
那么,用redis要如何落地呢?
有三种算法可以解决这个问题,分别是哈希取余分区、一致性哈希算法分区以及哈希槽分区。
一、哈希取余分区
公式为hash(key)%N,这个公式决定数据映射到哪个节点上。刚开始设计有用几个redis承载数据,n为几。在上图这个例子中,n为3,那么可以hash(key)%==0放第一台,hash(key)%==1放第二台,hash(key)%==2放第三台。
优点:简单易理解,可以起到负载均衡的作用。
缺点:扩容、缩容之后,映射关系需要重新计算,只适用于redis数量不变不故障的情况。
二、一致性哈希算法分区
算法分三步
1、构建一致性哈希环
一致性哈希环:将整个哈希值空间组成一个虚拟的圆环,假设某哈希函数H的值的空间为0-2^32-1,指针扫描到2^32-1后,下一个指向0。
2、服务器节点映射到哈希环上
每个服务器节点的IP地址或者主机名作为关键字哈希,来确定节点在环上的位置。
3、key根据落键规则落到服务器上
存储数据的时候,计算key的hash值,hash(key),这个key就落到哈希环上了,在此位置沿着环顺时针行走,找到第一个服务器,就将该值存储到该节点上。如下图所示,数据objectB,计算hash(objectB),落到圆环上后,顺时针找到了NodeB,并将值存储到NodeB上。
优点:扩容、缩容后,受影响的仅仅是一小段数据,其他数据不受影响。
如上图所示,NodeC宕机之后,NodeB和NodeC之间的数据会落到NodeD,其他节点不受影响。
如上图所示,新增节点NodeX,NodeA和NodeX之间的数据会落到NodeX上面,其他节点不受影响。
缺点:存在数据倾斜问题。换句话说就是,因为节点太少,节点分布不均,导致大量的数据缓存在一台服务器上,其他服务器很空闲。
三、哈希槽分区
在数据和节点之间加了一层哈希槽(slot),用于管理数据和节点之间的关系。这种解决方案很类似于为了解决住房问题,房东和房客之间会有中介,中介来处理房东和房客的需求匹配问题。
一个集群只能有16384(2^14-1)个槽,因为一般需求这个槽数够用了,再多会导致请求头超过8k,造成网络拥挤。
节点和槽的关系是slot=CRC16(key)%16384,根据求得的余数放到对应的槽里。
总结来说,小厂适用哈希取余分区,因为数据量不大,redis的数量一般固定。中厂适用一致性哈希算法分区,因为节点数量还算多,不太会出现数据倾斜问题,同时扩容缩容对数据影响不大,大厂适用哈希槽分区,小伙伴可以根据现实情况选择合适自己的解决方法。
注:该文章源于尚硅谷docker实战教程高阶篇分布式存储算法教程,本文章作者只做整理,加了一些自己的理解。