使用场景

当我们需要redis存储大量的数据时,只有一台redis服务器不能够满足需求;但如果扩大内容,由于需要长时间去寻址,也不能达到要求.
就需要另一种方式

Redis分片

说明

一般是采用多台Redis,分别去存储用户的数据,从而实现内存数据的扩容.
对于用户而言:会将Redis分片的多个Redis当作一个整体,不在乎数据存在那个中,只在乎能不能存储
分片的主要作用:实现内存的扩容

准备

1.创建目录
在redis根目录中创建一个shards目录
image
2.分片搭建
由于Redis启动是根据配置文件运行的,所以如果需要准备3台redis,则需要复制3份配置文件redis.conf. 端口号依次为6379/6380/6381.
命令:cp redis.conf shards/6379.conf/cp redis.conf shards/6380.conf/cp redis.conf shards/6381.conf
3.修改端口号
根据配置文件名称,动态修改对应的端口即可--文件中port修改
4.启动Redis
启动Redis服务:

 redis-server  6379.conf
 redis-server  6380.conf
 redis-server  6381.conf

通过ps -ef | grep redis检查服务是否启动.

入门案例

 /**
     * 测试Redis分片机制
     * 业务思路:
     *      用户需要通过API来操作3台redis.用户无需关心数据如何存储,
     *      只需要了解数据能否存储即可.
     */
    @Test
    public void testShards(){
        List<JedisShardInfo> list = new ArrayList<>();
        list.add(new JedisShardInfo("192.168.126.129", 6379));
        list.add(new JedisShardInfo("192.168.126.129", 6380));
        list.add(new JedisShardInfo("192.168.126.129", 6381));
        ShardedJedis shardedJedis = new ShardedJedis(list);
        shardedJedis.set("2020", "redis分片");
        System.out.println(shardedJedis.get("2020"));
    }

一致性hash算法

通过上边的入门案例,我们可以看到有输出的kv结果,证明我们的分片是成功进行了存储的,但是我们共启动了三个redis服务,我们通过服务端keys *命令的查找,也发现,其数据是存储在6381端口的redis中.
那么它是怎么判断存储在哪个redis中呢?--这就用到了hash一致性算法

介绍

百度介绍如下:
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题

hash

  1. 常见hash是8位16进制数
  2. 16进制数取值:0-9 A-F 共16个数
  3. hash的取值范围:00000000-FFFFFFFF(00000000与FFFFFFFFF是同一个数)
  4. 00000000-FFFFFFFF共有2^32个数
  5. 对相同的数据取hash值相同

一致性hash说明

步骤:
1.首先计算node节点hash值
2.将用户的key进行hash计算,之后按照顺时针的方向找到最近的node节点之后链接,执行set操作.
如图所示:
image

一致性hash特性

  1. 特性一--平衡性

平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题
说明: 如果发现节点中存储的数据负载不均,则采用虚拟节点的方式实现数据的平衡(相对平衡)
image

  1. 特性二--单调性

单调性是指在新增或者删减节点时,不影响系统正常运行,因为可以实现自动的数据迁移.
原则: 在进行数据迁移时 应该尽可能少的改变原有的数据.(只有发生迁移的移动,迁移到最近的节点)

  1. 特性三--分散性

分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据

SpringBoot整合Redis分片

分片说明

1.Redis分片的主要的作用是实现内存数据的扩容,Redis分片如果宕机不能实现高可用.
2.Redis的分片的计算发生在业务服务器(tomcat)中 将需要保存的数据存储到redis中.
3.Redis分片的执行的效率是最高的.(只负责存和取)

整合实现

1.编辑redis.properties配置文件

#配置多台的redis信息 redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381

2.编辑redis配置类

@Value("${redis.nodes}") 
private String nodes; //node,node,node 
/** 
* 添加Redis分片的配置 
* 需求1: 动态的获取IP地址/PORT端口 
* 动态的获取多个的节点信息. 方便以后扩展 
*/ 
@Bean 
public ShardedJedis shardedJedis(){ 
    List<JedisShardInfo> list = new ArrayList<>(); 
    String[] strArray = nodes.split(","); //[node,node,node] for (String node : strArray){ //ip:port 
        String host = node.split(":")[0]; 
        int port = Integer.parseInt(node.split(":")[1]); 
        list.add(new JedisShardInfo(host,port )); 
    } 
    return new ShardedJedis(list); 
}

3.修改AOP注入项-->将AOP缓存中的注入项改为分片对象

//注入缓存reids对象  
@Autowired  
private ShardedJedis jedis; //注入redis分片机制

只更改了类型并没改变名称,减少代码修改.


迈克丝
82 声望5 粉丝

一步一步学技术,踏踏实实涨经验,兴趣广泛,广交好友,希望大家多多指正/批评.