Redis从零到掌握学习整理

目录

1、NoSQL简介

1.1、NoSQL(Not Only SQL),不仅仅是是数据库,泛指非关系型数据库,以简单的key-value形式存储

1.2、适用场景

1.3、不适合场景

2、Redis概述

2.1、应用场景

2.1.1、配合关系型数据库做高速缓存

2.1.2、多样的数据结构存储持久化数据(也就是利用Redis可以做什么)

2.2、Redis安装:https://www.bilibili.com/video/BV1ga4y1v79L?p=7

2.3、Redis启动

2.4、客户端访问:redis-cli -p 6379

2.4.1、测试是否连通:ping

2.5、服务器的关闭

2.6、Redis相关知识

2.7、Redis底层采用的策略

2.7.1、与memcache的不同

3、常用五大类型

3.1、Redis键(key)

3.2、Redis字符串(String)

3.3、Redis列表(list)

3.4、Redis集合(set)

3.5、Redis哈希(hash)

3.6、Redis有序集合(zset)

4、Redis配置文件介绍

5、eclipse-spring boot访问Redis(maven)

5.1、所需jar

5.2、java简单构建短信验证码功能

5.3、spring boot使用连接池构建jedis

5.3.1、所需jar

 5.3.2、application.properties配置

5.3.3、java代码

6、Redis事务

6.1、multi、exec、discard

6.2.事务的错误处理

 6.3、实现秒杀功能:

7、Redis持久化

7.1、RDB

7.1.1、RDB原理

7.1.2、RDB优缺点

7.2、AOF

7.2.1、aof重写配置

7.2.2、aof优缺点

8、Redis主从复制

8.1、配置主从复制(一主二仆模式)

8.1.1、知识点

8.1.2、复制原理

8.2、薪火相传模式

8.2.1、薪火相传优缺点

8.2.2、反客为主

8.3、哨兵模式(一主二仆模式)

8.3.1配置哨兵模式

 8.3.2、哨兵原理

9、Redis集群

9.1、什么是集群

9.2、什么时候使用Redis集群?

9.3、配置集群(最少6个redis,3主3从)

9.3.1、集群命令

9.3.2、解决批量插入值报错问题

9.3.3、故障恢复

9.3.4、集群优缺点

9.4、插槽


 

官方网站:https://redis.io/

中文官网:http://www.Redis.net.cn

Redis数据类型命令参考:http://redisdoc.com/

1、NoSQL简介

1.1、NoSQL(Not Only SQL),不仅仅是是数据库,泛指非关系型数据库,以简单的key-value形式存储

  • 不支持ACID(事务的四个特性,原子性、一致性、隔离性、持久性)
  • 不遵循SQL标准。指不用写SQL就可以存储
  • 远超SQL性能

1.2、适用场景

  • 对数据的高并发的读写操作
  • 海量数据读写
  • 对数据的高可扩展性

1.3、不适合场景

  • 需要事务的支持
  • 基于SQL的结构化查询存储,处理复杂的关系,需要即席查询。即席:立即就查询出来的。指NoSQL适合存储和查询,不适合统计

2、Redis概述

  • 开源的key-value存储系统
  • 支持的value的类型:String(字符串)、list(链表)、set(集合)、zset(有序集合)、hash(map)
  • 支持存值/取值,取交集、并集和差集操作,这些操作都是原子性的
  • 支持不同方式的排序
  • 为了保证效率,数据都是缓存在内存中的
  • 支持持久化,周期性的将内存数据持久化存在磁盘内
  • 支持主从复制(master-slave),主机负责写操作,且主机数据会同步到从机,从机负责读操作。

2.1、应用场景

2.1.1、配合关系型数据库做高速缓存

  • 高频次,热门访问数据,降低数据库IO。例如某个新闻的访问量
  • 分布式架构,做session共享

2.1.2、多样的数据结构存储持久化数据(也就是利用Redis可以做什么)

  • zset:可以实现排行榜
  • 过期操作,例如手机的短信验证码失效时间
  • 实现商品的秒杀功能、计算器
  • set:彩票的随机数

2.2、Redis安装:https://www.bilibili.com/video/BV1ga4y1v79L?p=7

2.3、Redis启动

  • (建议)将Redis安装目录里的redis.conf文件拷贝出去(/myredis 目录),在复制后的redis.conf文件里修改
  • 将bind 127.0.0.1 注释掉,不注释掉表示只能本机访问redis服务器(redis所在的服务器)
  • protected-mode yes (保护模式),改为no
  • daemonize no (后台启动),改为yes

由于是编译安装的,它的命令都在/usr/local/bin 中(属于6个bin命令之一),所以在任何命令下执行

redis-server /myredis/redis.conf

2.4、客户端访问:redis-cli -p 6379

2.4.1、测试是否连通:ping

2.5、服务器的关闭

  • redis-cli -p 6379 shutdown 

  • 进入终端后再关闭

2.6、Redis相关知识

  1. 默认16个库,下标从0开始,默认使用0号库
  2. 使用select 下标 来切换库。例如:select 8 切换到了第九号库
  3. dbsize 查看当前数据库key的数量,keys * 可以查看所有key
  4. flushdb清空当前库,flushall清空所有库

2.7、Redis底层采用的策略

redis是单线程+多路IO复用技术,多路复用是指用一个线程检查多个文件的就绪状态。采用select或者poll函数或者xpoll函数,传入多个文件的状态,如果一个文件状态就绪,则返回,否则阻塞至超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(例如使用线程池)

知识点:

  1. select策略,线程循环的对每个文件进行询问就绪状态(询问是否就绪了),如果没有文件处于就绪状态,就会死循环的询问每个文件,直到有文件处于就绪状态,线程对该文件进行IO操作
  2. poll策略,线程不主动的询问文件的就绪状态,当某个文件处于就绪状态,会告知线程,这时线程会对每个文件进行询问就绪状态(一次循环的询问),找到该文件进行IO操作
  3. xpoll策略,和poll策略类似,线程不主动的询问文件的就绪状态,当某个文件处于就绪状态,会告知线程,这时线程不用询问每个文件,直接就知道是那个文件处于就绪状态,对该文件进行IO操作

2.7.1、与memcache的不同

  1. 支持多数据类型
  2. 支持持久化
  3. 单线程+多路IO复用

3、常用五大类型

3.1、Redis键(key)

  • keys * 查看当前库所有key
  • exists key 判断某个可以是否存在
  • type key 查看key是什么类型
  • del key 删除key
  • expire key 10 为给定的key设置过期时间(10秒)
  • ttl key 查看key还有多少秒过期,-1表示永不过期,-2表示已经过期
  • select 下标 切换数据库,下标从0开始到15,一共16个库
  • dbsize 查看当前数据库的key的数量
  • flushdb 清空当前数据库
  • flushall 清空所有数据库

3.2、Redis字符串(String)

String是二进制安全的。说明Redis的string可以包含任何数据。例如图片或者序列化的对象。最大是512M。

  • set key value 添加键值对,覆盖值
  • get key 查询值
  • append key value 将给定的value追加到原值的末尾
  • strlen key 获取值的长度
  • setnx key value 只有key不存在时设置key的值,如果存在则不进行覆盖值
  • incr key 将key中的值加1,只能对数值进行操作,如果为空,新增值为1
  • decr key 将key中的值减1,只能对数值进行操作,如果为空,新增值为-1
  • incrby key <步长> 将key的值根据步长新增
  • decrby key <步长> 将key的值根据步长减少
  • mset key1 value1 key2 value2... 同时设置多个key-value值
  • mget key1 key2 key3 同时获取多个key的值
  • msetnx key1 value1 key2 value2... 同时设置多个key-value值,当且仅当所有的key都不存在。该操作是原子性的,一个失败都失败
  • getrange key <起始位置> <结束位置>     获取值的范围,类似java中的substring,前包后包
  • setrang key <起始位置> value 用给定的value值,覆写key的值,从起始位置开始,下标从0开始
  • setex key <过期时间> value 设置键值的同时设置过期时间,单位秒
  • getset key value 以新换旧,设置新值同时获取旧值

知识点:

redis中的加加减减是原子性的,是安全的,在多线程中,该线程的操作不能被其他线程打断。

面试点:

java中的i++是原子性的吗?

答:不是。

i=0;两个线程分别对i进行++100次,最后i的值是多少?

答:2~200。

讲解的案列视频:https://www.bilibili.com/video/BV1ga4y1v79L?p=13    大概八分钟

3.3、Redis列表(list)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加元素到列表的头部(左边)或者尾部(右边)。它的底层实际是个双向链表,对两端的操作性高。

  • lpush/rpush key value1 value2 value3 ... 从左边/右边插入一个或者多个值

  • lpop/rpop key 从左侧/右侧吐出一个值。该值从list中删除了

  • rpoplpush key1 key2 从key1右侧取出一个值,从左侧放到key2中

  • lrange key start end 按照索引下标获取元素(从左到右)。列表中的值还在。lrange key 0 -1 从0开始,-1表示所有

  • lindex key index 按照索引下标获取元素(从左到右)。列表中的值还在。

  • llen key 获取列表长度 
  • linsert key before/after value newvalue 在原有的值(value:key中的某个下标的值)后面插入新值

  • lrem key n value 从左边删除n个value(从左到右),例如删除key中的2个“A”

3.4、Redis集合(set)

Redis的set是string类型的无序集合。它的底层其实是一个value为null的hash表,所以删除、添加、查找的复杂度都是O(1)

  • sadd key value1 value2 将一个或多个元素添加到集合中,已存在的忽略。
  • smembers key 取出所有值
  • sismember key value 判断集合中是否含有该value值,存在返回1,没有返回0
  • scard key 返回集合元素个数
  • srem key value1 value2 删除集合中的某个元素
  • spop key 随机从集合中吐出一个值,会删除元素,元素全部吐出后,key消失
  • srandmember key n 随机从集合中吐出n个值,不会删除元素
  • sinter key1 key2 返回交集元素
  • sunion key1 key2 返回并集元素
  • sdiff key1 key2 返回差集元素,注意:key1和key2的前后顺序不同,会造成结果的不同

3.5、Redis哈希(hash)

Redis hash是一个键值对集合,相当于 value的值是Map,是一个string类型的field和value的映射表,特别适合存储对象。

  • hset key field value 给key中的field键赋值value
  • hget key1 field 从key1集合的field键中取出值

  • hmset key1 field1 value1 field2 value2 批量设置值
  • hexists key field 查看key中是否存在field,0表示没有,1表示有
  • hkeys key 列出key中所有的field
  • hvals key 列出key中所有的value值

  • hincrby key field increment 为key中的field的值加上增量increment 
  • hsetnx key field value 将key中的field的值设置成value,当且仅当field不存在

3.6、Redis有序集合(zset)

Redis的zset 和set非常相似,是一个没有重复元素的字符串集合。不同是zset关联了一个评分(score),这个score被用来按照从最低分到最高分的方式排序集合中的元素。score是可以重复的。可用zset来做排行榜功能。

  • zadd key score1 value1 score2 value2 将一个或多个元素及其score值加入到可以中
  • zrange key start end [withscores] 将key中下标在start和end之间的元素返回,带withscores,可以让分数和元素一起返回。zrange key 0 -1 表示全部取出。

  • zrangebyscore key min max [withscores] [limit offset count] 返回key中所有score值在min和max之间(min<=score<= max)的元素。按score的值从小到大排序。可选的 limit参数指定返回结果的数量及区间(就像SQL中的 select limit offset, count ),注意当 offset 很大时,定位 offset 的操作可能需要遍历整个有序集

  • zrevrangebyscore key max min [withscores] [limit offset count] 返回key中所有score值在min和max之间(min<=score<= max)的元素。按score的值从大到小排序。

  • zincrby key increment value 为元素的score加上增量increment

  • zrem key value 删除指定值的元素
  • zcount key min max 统计集合,分数区间内的元素个数
  • zrank key value 返回该值在集合中的排名,从0开始

4、Redis配置文件介绍

  1. bind 127.0.0.1 表是支持绑定ip的机器可以访问Redis服务,多个ip之间用空格分开,一般注释掉(推荐),表示所有机器都可以访问Redis
  2. protected-mode yes 保护模式,一般改为no,和bind一起配置的
  3. port 端口号
  4. daemonize no 启动方式,改为yes(后台启动)
  5. dbfilename dump.rdb 持久化RDB文件的名称配置
  6. appendfsync everysec  AOF文件的同步频率,默认每秒同步操作步骤

5、eclipse-spring boot访问Redis(maven)

5.1、所需jar

<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

5.2、java简单构建短信验证码功能

/**
	 * 获取短信验证码
	 */
void getCode() {
		// 前台获取的手机号
		String phone = "13694198150";
		// 设置每天发送次数
		int maxNum = 3;
		// 连接redis,ip+port
		Jedis jedis = new Jedis("211.137.43.228", 6379);
//		ValueOperations opsForValue = redisTemplate.opsForValue();
		// 发送次数key
		String countKey = phone + "_count";
//		String string = (String) opsForValue.get(countKey);
		// 获取历史发送次数
		String phoneCount = jedis.get(countKey);
		if (phoneCount == null) {// 当天没发送过验证码
			// 设置发送次数(第一次),且设置失效时间:一天
			jedis.setex(countKey, 24 * 60 * 60, "1");
//			opsForValue.set(countKey, "1", 24 * 60 * 60, TimeUnit.SECONDS);//会自动关闭连接
		} else {// 当天发送过
			// 判断是否超过每天的发送限制
			if (Integer.valueOf(phoneCount) >= maxNum) {
				System.err.println("每天发送短信超过次数了");
				jedis.close();
			} else {
				jedis.incr(countKey);
			}
		}
		// 获取验证码
		String code = "1234";
		String codeKey = phone + "_code";
		// 设置5分钟有效
		jedis.setex(codeKey, 60 * 5, code);
		jedis.close();
		// 发送验证码给手机

		System.out.println("验证码:" + code);
	}
/**
	 * 校验验证码
	 */
	void checkCode() {
		// 获取前台手机号
		String phone = "13694198150";
		// 获取前台验证码
		String code = "123456";
		// 从redis中获取验证码
		String codeKey = phone + "_code";
		Jedis jedis = new Jedis("211.137.43.228", 6379);
		String redisCode = jedis.get(codeKey);
		jedis.close();
		if (redisCode == null) {
			System.out.println("验证码已失效");
		} else if (!code.equals(redisCode)) {
			System.out.println("验证码不正确");
		} else {
			System.out.println("验证成功");
		}
	}

5.3、spring boot使用连接池构建jedis

5.3.1、所需jar

<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>
		<dependency>
		    <groupId>org.springframework.data</groupId>
		    <artifactId>spring-data-redis</artifactId>
		</dependency>

 5.3.2、application.properties配置

# Redis配置
## Redis数据库索引(默认为0)
spring.redis.database=0
## Redis服务器地址
spring.redis.host=127.0.0.1
## Redis服务器连接端口
spring.redis.port=6379
## Redis服务器连接密码(默认为空)
spring.redis.password=
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
## 连接池最大空闲连接
spring.redis.jedis.pool.max-idle=8
## 连接池最小空闲连接
spring.redis.jedis.pool.min-idle=0
## 连接超时时间(毫秒)
spring.redis.timeout=0

5.3.3、java代码

@Resource
	RedisTemplate redisTemplate;

void test(){
    ValueOperations opsForValue = redisTemplate.opsForValue();
    String string = (String) opsForValue.get(countKey);
    // 设置发送次数(第一次),且设置失效时间:一天
    opsForValue.set(countKey, "1", 24 * 60 * 60, TimeUnit.SECONDS);//会自动关闭连接
}

6、Redis事务

Redis的事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序的执行。事务在执行的过程中,不会被其他客户端发来的命令打断。

Redis事务的主要作用就是串联多个命令,防止其他命令插队

6.1、multi、exec、discard

从输入multi开始,输入的命令一次进入队列,但不会执行,知道输入exec后,命令才会依次执行。组队过程中可以用discard来放弃组队

6.2.事务的错误处理

  • 1、组队过程中某个命令出现错误,执行时整个队列中的命令都取消,一个都没执行

 

  • 2、执行过程中某个命令出现错误,则只有报错的命令不会执行,其他命令继续执行

 6.3、实现秒杀功能:

https://www.bilibili.com/video/BV154411r71N?p=10   32:32秒

6.4、Redis事务的特性

  1. 单独的隔离操作。所有的命令都序列化。按顺序的执行,不能被打断
  2. 没有隔离级别的概念。队列中的命令在没有提交前,不会被真正的执行
  3. 不保证原子性。参考6.2

7、Redis持久化

Redis持久化提供了2中形式,RDB和AOF

7.1、RDB

在指定时间间隔内将内存中的数据快照到磁盘内。文件后缀  .rdb

7.1.1、RDB原理

操作Redis的线程会复制一个和自己任何东西都相同的线程fork(子线程),fork会将数据写入到一个临时的文件中,待持久化结束,再用这个临时文件替换磁盘内的已经持久化的文件。整个过程主线程不做任何IO操作。当主进程没做任何操作时,主进程和子进程共用同一个物理内存,当主进程进行写入时,子进程会复制一份内存。也就是Linux的“写时复制技术”。

7.1.2、RDB优缺点

  • 有点对于恢复大规模数据快
  • 最后一次持久化后的数据可能会丢失
  • 对于内存大小要求高,因为会存在两倍的数据(主线程的redis数据和fork临时文件数据)

7.2、AOF

将Redis执行的所有操作以日志的形式记录(读操作不记录),redis启动之初会读取该文件重新构建数据,也就是将所有写操作执行一遍。

  • AOF默认不开启,appendonly no 改为yes,
  • 持久化的文件名称默认是appendonly.aof,它是可编辑的文件(vim),文件同RDB文件同目录。 
  • 如果修改aof文件,使文件损坏,执行redis-check-aof --fix appendonly.aof 进行恢复
  • aof采用文件追加的方式(在aof文件的末尾追加写命令),指aof的文件会越来越大,为了避免此情况,新增了重写机制,当aof文件大小超过设定的值时,Redis会启动aof文件内容压缩,只保留可以恢复数据的最小指令集。可以使用bgrewriteof。例如set k1 100, incr k1,两个命令可以直接改写成set k1 101

7.2.1、aof重写配置

  • auto-aof-rewrite-precentage 100 达到设定重写大小值的百分比(1+100%),设置重写大小为64M,达到128M开始重写。公式:AOF当前大小>=baseSize + baseSize * 100%,且当前大小大于等于64MB(默认)的情况下。
  • auto-aof-rewrite-min-size 64mb 设定重写的大小

7.2.2、aof优缺点

  • 丢失数据小
  • 可读写文件,通过操作aof文件可以处理失误操作
  • 比RDB占用磁盘多
  • 恢复速度慢
  • 每次写操作都需要记录,有一定性能压力

8、Redis主从复制

主从复制,就是主机数据更新后根据配置和策略,自动更新同步到从机上的机制。Master以写为主,Slave以读为主。

8.1、配置主从复制(一主二仆模式)

本次配置一台主机,两台从机

  1. 新建3份conf文件(空白的),命名为redis_6379.conf,(名字随便)此为主机配置文件;其他两个分别为redis_6380.conf和redis_6381.conf,此两个为从机配置文件,
  2. 主机配置文件中编辑,新增: include /redis.conf 的绝对路径/redis.conf,表示包含原有的redis.conf的所有配置;但是需要从新覆盖一个配置(如果在原有的redis.conf 里改过就不需要改了),例如daemonize 改为yes,pidfile /路径/redis_6379.pid,port 改为 6379 ,dbfilename 重命名dump_6379.rdb,关掉aof,appendonly 改为 no
  3. 其他从机和主机配置类似
  4. 根据相应的redis_*.conf 来启动Redis
  5. Redis客户端分别连接Redis服务器,redis-cli -p 6379,redis-cli -p 6380,redis-cli -p 6381
  6. 打印三台Redis的主从关系,info replication ,刚开始三台机器都是主机,需要配置主从关系
  7. 在从机上(你想要此机器成为从机的机器上),执行slaveof <ip> <port> ,表示该机器的redis成为某个redis的从机。例如:6380端口的redis想要成为6379端口的redis的从机,slaveof 211.137.0.0.1(6379所在机器的IP) 6379,表示成为211.137.0.0.1 IP上的端口号为6379的Redis的从机
  8.  

主机配置: 

从机配置:

 启动redis:

主从关系:配置前三台机器的信息都一样

主从关系:配置后

8.1.1、知识点

  • 后加入的从机的数据是从主机数据从头开始复制的,就是说从机数据和主机数据一样
  • 从机不能有写操作(写操作或报错)
  • 主机shutdown后,从机原地待命,还是从机角色,不能变成主机,待到主机重启后再次连接
  • 从机shutdown后再次启动,则不能自动连接原来的主机,该从机角色变成主机了,解决:在从机配置文件内加上:slaveof <ip> <port>,则从机shutdown后再重启就会执行该操作,角色变成从机

8.1.2、复制原理

  • 每次从机联通后,会给主机发送同步命令
  • 主机接收到后立即进行存盘操作,发送rdb文件给从机
  • 从机接收到rdb文件后,进行全盘加载
  • 之后每次主机的写操作,都会立即发送从机,从机执行相同的命令

8.2、薪火相传模式

经过配置后,中间的从机的信息:

8.2.1、薪火相传优缺点

  • 提升主机性能,减轻主机发送给从机数据的压力
  • 一旦某个中间节点的从机宕机,该从机后面的从机无法获取数据

8.2.2、反客为主

主机宕机后,如何让从机变成主机。从机上执行 slaveof no one 命令

8.3、哨兵模式(一主二仆模式)

后台监控主机是否宕机(心跳机制:每隔一段时间发送 ping命令,看是否 有pong 回来),如果故障了根据投票数自动将从机变成主机

8.3.1配置哨兵模式

  • 调整为一主二仆模式
  • 在redis_6379.conf 同目录下新增sentinel.conf 文件,文件名称不能改,
  • 在文件里编辑,sentinel monitor mymaster 127.0.0.1 6379 1,其中mymaster 为监控对象起的服务器名称(哨兵的别名,随便起),127.0.0.1 为主机地址,1 为至少有多少个哨兵同意主机死掉了,可以将从机变成主机
  • 启动哨兵,执行 redis-sentinel  /地址/sentinel.conf 

当主机宕机后,哨兵将从机变成主机,如果之前的主机再次启动后,将变成从机

 8.3.2、哨兵原理

  • 在从机中首先挑选优先级大的从机。优先级:redis.conf 配置文件中:slave-priority 100,100最小 ,如果值是 0 表示永远不能当主机
  • 其次优先级相同的从机,选择偏移量最大的。偏移量:指获得原主数据最多的
  • 最后优先级和偏移量都相同,选择runid最小的从机。runid:每个redis实例启动后,都会随机生成一个40位的runid
  • 选出从机后,sentinel向从机发送slaveof no one 命令。
  • 如果原主机重启后,sentinel向该主机发送 slaveof <ip> <port>命令。

9、Redis集群

9.1、什么是集群

  • Redis集群实现了对Redis的水平扩容,即启动N个redis节点,将整个redis数据库分布储存在N个节点上,每个节点的数据是总数据的1/N。
  • Redis集群通过分区来提供一定程度的可用性:即使集群中的某个节点失效,集群也可以继续处理请求。

9.2、什么时候使用Redis集群?

  1. 当一台主机的内存不够时。
  2. 当高并发的写操作时。

9.3、配置集群(最少6个redis,3主3从)

注意:配置集群需要数据从0开始,即redis不能存数据,将rdb文件和aof文件删除

  • 安装集群环境:https://www.bilibili.com/video/BV154411r71N?p=15   38:26 
  • 新建6个redis.conf文件
  • 每个文件配置集群信息。下面图文,其中超时时间单位:毫秒
  • 将6个redis节点合成集群,进入redis安装包目录的src 文件夹下
  • 执行:./redis-trib.rb create --replicas 1 <ip>:<port> <ip>:<port> <ip>:<port> <ip>:<port> <ip>:<port> <ip>:<port>,此处的IP为真实的IP,不能是127.0.0.1。其中 --replicas 1 表示为每个主节点配置几个从节点
  • 连接集群,连接集群中任何的主机都可以,三个主机相当于一个整体,redis-cli -c -p 6380

当进行写操作时,集群会计算你设置的key(set k1 v1 中的k1)属于哪个插槽,然后重定向到该插槽所在的redis

9.3.1、集群命令

  • cluster nodes 查看集群信息
  • cluster keyslot <key> 计算key应该放在哪个槽点上,返回的是插槽下标
  • cluster countkeysinslot <slot> 返回插槽slot 中包含的键值对数量
  • cluster getkeysinslot <slot> <count> 返回count个slot中的键

9.3.2、解决批量插入值报错问题

Redis集群设置的key,如果不在同一个节点上,例如:键k1、k2、k3,经过集群计算,分别属于不同的Master,则不能执行批量的操作,如mset 命令,mget 命令

解决:在键后面加上{} ,可以通过{}来定义组的概念,大括号里是别名,随便起

9.3.3、故障恢复

  • 主节点下线,从节点自动变成主节点
  • 主节点恢复后变成从节点
  • 如果所有某一段插槽的主从节点都停掉,
  1. 若果关心数据的话,在配置文件中配置,进群停掉
  2. 如果不关心数据,集群不停掉,继续使用,但某些数据获取不到了。
  3. redis.conf 配置:cluster-require-full-coverage,当为 yes 时是情况1,当为 no 时是情况2

将某个主节点停掉后集群信息:6379端口的主节点停掉,6389端口的从节点变成主节点

当再次将原主节点启动,原主节点变成从节点

9.3.4、集群优缺点

优点:

  • 实现扩容
  • 分摊压力
  • 无中心配置

缺点:

  • 多键操作不支持,实际是支持的不好,需要定义组概念,{}。
  • 多键事务不支持,lua脚本不支持
  • 集群的迁移麻烦,复杂度大

9.4、插槽

 一个Redis集群包含16384个插槽,插槽下标从0开始,数据库中的每个key都属于这些插槽中,集群使用公式CRC16(key)% 16384,来计算key属于哪个插槽。上面图片第一个Master分配了5461个槽点,下标为 0~5460 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值