一、Redis 的 五大数据类型

1、key

指令

描述

keys *

查看当前库的所有键

exists<key>

判断某个键是否存在

type<key>

查看键的类型

del<key>

删除某个键

expire<key><seconds>

为键设置过期的时间,单位秒

ttl<key>

查看还有多久过期,-1 表示永不过期,-2表示已过期

dbsize

查看当前数据库中的key的数量

flushdb

清空当前库

Flushall

通杀全部库

2、String

  1. String 是 Redis 最基本的类型。
  2. String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如 jpg 图片或者序列化的对象。
  3. String 类型是Redis 最基本的数据类型,一个Redis 中字符串value 最多可以是512M
  4. 常用操作

指令

描述

get<key>

查询对应的键值

set <key><value>

添加键值对

append<key><value>

将给定的<value> 追加到原值的末尾

strlen<key>

获取值的长度

setnx<key><value>

只有在Key 不存在时设置 key 的值

incr<key>

将key中存储的数字值增1, 只能对数字值的操作,如果为空,新增值为1。

decr<key>

将key 中存储的数字值减1,只能对数字值操作,如果为空,新增值为-1

incrby/ decrby <key><步长>

将 key 中存储的数字值增减。自定义步长。

mset<key1><value1><key2><value2>

同时设置一个或多个key-value对

mget<key1><key2><key3>

同时获取一个或多个key-value对

msetnx<key1><value1><key2><value2>

同时设置一个或多个key-value对,当且仅当所有给定的key都不存在

getrange<key><起始位置><结束位置>

获取值的范围,类似java 中的substring

setrange<key> <起始位置> <value>

用<vakue>覆盖<key>所存储的字符串值,从<起始位置>开始

setex<key><过期时间><value>

设置键值的同时,设置过去的时间,单位秒

getset<key><value>

以新换旧,设置了新值的同时获取旧值

  1. incr key 操作的原子性
  • 所谓的原子是指不会被线程的调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何的 context switch (切换到另一个线程)。
  • 在单线程中,能够在单条指令中完成的操作都可以认为是"原子操作",因为中断只能发生在于指令之间。
  • 在多线程中,不能被其他的进程(线程)打断的操作就叫原子操作。
  • Redis 单命令的原子性主要得益于 Redis 的单线程

3、List

  1. 单键多值
  2. Redis ;列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素列表的头部(左边) 或者尾部 (右边)。
  3. 它的底层实际是一个双向链表,对两端的操作行选性能很高,通过索引下标的操作中间的节点性能会差
  4. 常用操作

指令

描述

lpush/rpush<key><value1><value2>

从左边/右边插入一个值或多个值

lpoy/rpop <key>

从左边/右边吐出一个值。

值在键在,值光键亡。

rpoplush<key1><key2>

从<key1>列表边吐出一个值,插到<key2>列表的左边

lrange<key><start><stop>

按照索引下标获取元素(从左到右)

lindex<key><index>

按照索引下标获取的元素(从左到右)

llen<key>

获得列表长度

linsert<key> before<value> <newvalue>

在<value>的后面的插入<newvalue> 插入值

lrem<key><n><vakue>

从左边删除n个value(从左到右)

4、Set

  1. Redis set对外提供的功能与list 类似是一个列表功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现一个重复的数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否存在一个 set 集合内的重要接口,这个也是 list 所不能提供的。
  2. Rdis 的 set 是 String 类型的无序集合。它底层其实是一个value为null 的 hash 表,所以添加,删除,查找的复杂度都是O(1)。
  3. 常用操作

方法

描述

setadd<key><value1><value2>…

将一个或多个 menber 元素加入到集合 key 当中,

已经存于集合的 menber 元素将忽略

smembers<key>

取出该集合的所有值。

sismember<key><value>

判断一个集合<key>是否含有该<value>值,有返回值1,没有返回0

scard <key>

返回该集合的元素个数

srem<key><value1><value2>…

删除集合中的某个元素

spop<key>

随机从该集合中吐出一个值

srandmenber<key><n>

随机从该集合中取出n个值。不会从集合中删除

sinter<key1><key2>

返回两个集合的交集元素

sunion<key1><key2>

返回两个集合的并集元素

sdiff<key1><key2>

返回两个集合的差集元素

5、Hash

  1. Redis hash 是一键值对集合
  2. Redis hash 是一个string 类型的 field 和 value 的映射表,hash 特点适用用于存储对象。
  3. 类似 java 里面的 Map<String,Object>
  4. 分析一个问题:现有一个JavaBean 对象,在Redis 中如何存?
  • 第一种方案:用户ID 为key,VALUE 为 JavaBean 序列化后的字符串

java redis原子操作 redis原子操作有哪些_数据

缺点:每次修改的用户的某个属性需要,先反序列化改好后在序列化回去。开销较大

  • 第二种方案:用户ID+属性名作为key属性值作为Value.

java redis原子操作 redis原子操作有哪些_java redis原子操作_02

缺点:用户 ID 数据冗余

  • 第三种方案:通过 key(用户 ID) + filed(属性标签) 就可以操作对应的属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。

java redis原子操作 redis原子操作有哪些_数据_03

  1. 常用操作

方法

描述

hset<key> <field><value>

给<key>集合中的<field>键赋值<value>

hmset<key1><field>

从<key1>集合<field> 取出 value

hmset<key1><field1><value1> <field2> <value2>…

批量设置 hash的值

hexists key <field>

查看哈希表 key 中,给定域 field 是否存在

hkeys<key>

列出该hash 集合的所有的 field

hvals<key>

列出该hash 集合的所有value

hincrby<key><field><increment>

为哈希表 key 中的域 field 的值加上增量 increment

hsetnx <key> <field><value>

将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在

6、zset(sorted ser)

  1. Redis 有序集合 zset 与 普通的 set 非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联一个评分(sroce), 这个评分(score) 被用来按照从最低的分到最高的方式排序集合中的成员。集合中的成员是唯一的,但是评分可以是重复了。
  2. 因为元素是有序的,所以你也可以很快的根据评分(score) 或者次序(position)来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复的成员的智能列表。
  3. 常用操作

方法

描述

zadd <key> <score1> <value1> <score2> <value2>…

将一个或多个 member 元素及其 score 值加入到有序集合 key 当中

zrange<key> <start><stop>[WINHSCORES]

返回有序集 key 中,下标在<start><stop>之间的元素带WITHSCORES,可以让分数一起和值返回到结果集。

zrangebyscore key min max [withscores] [limit offset count]

返回有序集合 key 中, 所有 score 值介于 min 和 max 之间(包括等于 min 或 max) 的成员。有序集合按score 值递增(从小到大)次序排列。

zrevrangebyscore key max min [withscores] [limit offset count]

同上,改为从大到小排列。

zincrby <key> <increment> <value>

为元素的score 加上增量

zrem<key><value>

删除集合下,指定值的元素

zcount<key><min><max>

统计该集合,分数区间内的元素个数

zran<key> <value>

返回该值在集合中排名,从0开始。

二、Redis 的相关配置

  1. 计量单位说明,大小写不敏感
  2. include
    类似 jsp 中的 include,多实例的情况可以把公用的配置文件提取出来
  3. ip 地址的绑定 bind
  • 默认情况 bind=127.0.0.1 只能接受本机的访问请求
  • 不写的情况下,无限制接受任何 ip 地址的访问
  • 生产环境肯定要写你应用服务器的地址
  • 如果开启了 protected-mode,那么在没有设定 bind ip 且没有设密码的情况下, Redis 只允许接受本机的相应
  1. tcp-backlog
  • 可以理解是一个请求到达后至到接受进程处理前的队列
  • backlog 队列总和=未完成三次握手队列 + 已经完成三次握手队列
  • 高并发环境 tcp-backlog 设置值跟超时时限内的 Redis 吞吐量决定
  1. timeout
    一个空闲的客户端维持多少秒会关闭, 0 为永不关闭。
  2. tcp keepalive
    对访问客户端的一种心跳检测,每个 n 秒检测一次,官方推荐设置为 60 秒
  3. daemonize
    是否为后台进程
  4. pidfile
    存放 pid 文件的位置,每个实例会产生一个不同的 pid 文件
  5. log level
    四个级别根据使用阶段来选择,生产环境选择 notice 或者 warning
  6. log level
    日志文件名称
  7. syslog
    是否将 Redis 日志输送到 linux 系统日志服务中
  8. syslog-ident
    日志的标志
  9. syslog-facility
    输出日志的设备
  10. database
    设定库的数量 默认 16
  11. security
    在命令行中设置密码

java redis原子操作 redis原子操作有哪些_Redis_04

  1. maxclient
    最大客户端连接数
  2. maxmemory
    设置Redis 可以使用的内存量。一旦到达内存使用上限, Redis 将会试图移除内部数据,移除规则可以通过 maxmemory-policy 来指定。如果 Redis 无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么 Redis 则会针对那些需要申请内存的指令返回错误信息,比如 SET、 LPUSH 等。
  3. Maxmemory-policy
  • volatile-lru: 使用 LRU 算法移除key, 只对设置了过期时间的键
  • allkeys-lru:使用 LRU 算法移除 key
  • volatile-random:在过期集合中移除随机的 key,只对设置了过期时间的键
  • allkeys-random:移除随机的 key
  • volatile-ttl:移除那些 TTL 值最小的 key,即那些最近要过期的 key
  • noeviction:不进行移除。针对写操作,只是返回错误信息
  1. Maxmemory-samples
    设置样本数量, LRU 算法和最小 TTL 算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小。一般设置 3 到 7的数字,数值越小样本越不准确,但是性能消耗也越小。

三、Redis 的 Java 客户端 Jedis

1、Jedis 所需要的 jar 包,可以通过 Maven 的依赖引入

java redis原子操作 redis原子操作有哪些_Redis_05

  1. 使用 Windows 环境下 Idea 连接虚拟机中的 Redis 注意事项
  • 禁用 Linux 的防火墙: Linux(CentOS7)里执行命令 : systemctl stop firewalld.service
  • redis.conf 中注释掉 bind 127.0.0.1 ,然后 protect-mode no。
  1. Jedis 测试连通性 :
public class JedisTest {
    public static void main(String[] args) {
        // 连接本地 Redis 服务
        Jedis jedis = new Jedis("192.168.64.129",6379);

        // 查看服务是否运行,打出pong 表示OK
        System.out.println("connection is OK =====>:" + jedis.ping());
    }
}

四、 Redis 事务

1、Redis 中的事务的定义

Redis 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。Redis 事务的主要作用就是串联多个命令防止别的命令插队。

2、multi、exec、discard

  1. 从输入 Multi 命令开始,输入的命令都会依次进入执行命令列中,单不会执行,至到输入Exec后,Redis 会将之前的命令依次执行。
  2. 组队的过程中可以通过discard 来放弃组队。

java redis原子操作 redis原子操作有哪些_有序集合_06

3、事务中的错误处理

  1. 组队中的某个命令出现了报告错误,执行时整个的所有队列都会别取消。

java redis原子操作 redis原子操作有哪些_java redis原子操作_07

  1. 如果执行阶段某个命令出现了错误,则只有报错的命令不会被执行,而其他的命令会执行,不会回滚。

java redis原子操作 redis原子操作有哪些_有序集合_08

4、通过事务解决问题

java redis原子操作 redis原子操作有哪些_java redis原子操作_09

  • 悲观锁(Pessimistic Lock) ,顾名思义,就是很悲观,每次去拿数据的时候都被认为别人会修改,所以每次在那数据的时候都会上锁,这样别人想拿这个数据就会 block 直接它拿到锁。传统的关系型数据库里边就用到了很多这样的机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
  • 乐观锁(Optimistic Lock) ,顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下再此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis 就是利用这种 check-and-set 机制实现的事务。

5、Redis 事务的使用

  1. WACH key[key…]
    在执行 multi之前, 先执行 watch key1[key2], 可以监视一个(或多个)key,如果在事务执行之前这个(或这些)Key 被其他命令所改动,那么事务将被打断。
  2. unwatch

取消WATCH 命令对所有 key 监视。如果执行 WATCH命令之后,EXEC命令或DISCAED 命令先被执行了的话,那么就不需要在执行UNWINAH了。

  1. 三特性
  • 单独的隔离操作
    事务中的所有命令都会被序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发来的命令请求所打断。
  • 没有隔离级别的概念
    队列中的命令没有被提交之前都不会实际的被执行,因为事务提交前的任何指令都不会被实际执行,也就不存在"事务内的查询要看到事务里的更新,在事务外查询不能看到"
  • 不保证原子性
    Redis 同一个事务中如果有一条命令执行失败,其后的命令仍会被执行,没有回滚

五、Redis 持久化

Redis 提供 2 个不用形式的持久化方式 RDB 和 AOF

1、RDB

  1. 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的 Snapshot 快照,它恢复时是将快照文件直接读到内存里。
  2. 备份的执行:Redis会单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中,待持久化进程都结束,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何的IO操作的,这就是确保了极高的性能如果需要进行大规模的数据恢复,且对数据恢复的完整性不是非常敏感,那RDB 方式要比 AOF 方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
  3. fork: 在Linux 程序中,fork() 会产生一个和父进程完全相同的子进程,但子进程在此后多会exec 系统调用,出于效率考虑,Linux 中引入”写时复制技术“,一般情况父进程和子进程会共同一段物理内存,只有进程空间的各段的内容要发生变化时,才会父进程的内容复制一份个子进程。
  4. RDB 保存的文件
    在redis.conf 中的配置文件,默认为 dump. rdb
  5. RDB 文件的保存路径
    默认为 Redis 启动时命令所在的目录下,也可以修改
  6. RDB 的保存策略

java redis原子操作 redis原子操作有哪些_有序集合_10

java redis原子操作 redis原子操作有哪些_数据_11

  1. 手动保存快照
    save:只管保存,其他不管,全部阻塞
    bgsave: 按照保存策略的自动保存
  2. RDB 的相关配置
  • stop-writes-on-bgsave-error yes
    当Redis 无法写入磁盘的话,直接关闭 Redis 的写入操作。
  • rdbcompression yes
    进行 rdb 保存时,将文件压缩
  • rdbchecksum yes
    在存储的快照后,还可以让 Redis 使用CRC64 算法来进行数据校验,但是这样做会增加大约10% 的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
  1. RDB 的备份 与恢复
  • 备份:先通过 config get dir 查询 rdb 文件的目录 , 将*.rdb 的文件拷贝到别的地方
  • 恢复: 关闭 Redis,把备份的文件拷贝到工作目录下,启动 redis,备份数据会直接加载。
  1. RDB 的优缺点
  • 优点: 节省磁盘空间,恢复速度快.
  • 缺点:虽然Redis 在fork 时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。在备份周期在一定的间隔时间做一次备份,所有如果 Redis 意外 down 掉的话,就会失去最后一个快照后的所有修改。

2、AOF

  1. 以日志的形式来记录每个写的操作,将Redis执行的过程的所有写的指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis 启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写的指令从前到后执行一次以完成数据的恢复工作。
  2. AOF 默认不开启,需要手动在配置文件中配置。

java redis原子操作 redis原子操作有哪些_数据_12

  1. 可以在 redis.conf 中配置文件名称,默认为 appendonly.aof

java redis原子操作 redis原子操作有哪些_数据_13

AOF 文件的保存路径,同 RDB 的路径一致

  1. AOF 文件故障备份

AOF 的备份机制和性能虽然和 RDB 不同,但是备份和恢复的操作 RDB一样,都是拷贝文件,需要恢复时再拷贝到Redis 工作目录下,启动系统即加载

  1. AOF 文件故障恢复
    如遇到 AOF 文件损坏,可通过 redis-check-aof --fix appendonly.aof 进行恢复
  2. AOF 同步频率设置
  • 始终同步,每次 Redis 的写入都会立刻记入日志 。
  • 每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
  • 把不主动进行同步,把同步时机交给操作系统。
  1. Rewrite
  • AOF 采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当 AOF文件的大小超过所设定的阈值时, Redis 就会启动 AOF 文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令 bgrewriteaof。
  • Redis 实现重写:AOF文件持续增长而过大时,会fork出一条新进程来将3文件重写(也是先写临时文件最后写 rename),遍历新进程的内存中的数据,每条记录有一条的Set 语句。重写的aof文件的操作,并没有读取旧的aof 文件,而是将整个内存中的数据库名内容用命令的方式重写了一个新的 aof文件,这点和快照有点类似。
  • 何时重写: 重写虽然可以节省大量的磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定 Redis 要满足一定条件才会进行重写。

java redis原子操作 redis原子操作有哪些_java redis原子操作_14

系统载入时或者上次重写完毕时,Redis 会记录此时的 AOF 大写,设为base_size,如果 Redisde AOF 当前大小 >= base_size + base_size*100%(默认)且当前大小>=64mb(默认)的情况下,Redis 会对 AOF 进行重写。

  1. AOF 的优缺点
  • 优点:
    备份机制更稳点,丢失数据概率更低。
    可读的日志文本,通过操作 AOF 稳健,可以处理误操作。
  • 缺点:
    比起 RDB 占用更多的磁盘空间
    恢复备份速度要慢
    每次读写都同步的话,有一定的性能压力。

3、RDB 和 AOF 用哪个好

  • 官方推荐两个都启用。
  • 如果对数据不敏感,可以选单独用RDB
  • 不建议单独使用 AOF, 因为可能会出现 Bug。
  • 如果只是做内存缓存,可以都不用

六、Redis 主从复制

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

1、主从复制的目的

  1. 读写分离,性能扩展
  2. 容灾快速恢复

2、主从配置

  1. 原则:配从不配主
  2. 步骤: 准备三个 Redis 实例,一主两从
  • 拷贝多个 redis.conf 文件 include
  • 开启 daemonize yes
  • pid 文件名字 pidfile
  • 指定端口 port
  • Log 文件名字
  • Dump.rdb 名字 dbfilename
  • Appendonly 关闭或换掉名字
include /opt/myRedis/redis.conf
pidfile /var/run/redis6381.pid
port 6381
dbfilename dump6381.rdb

java redis原子操作 redis原子操作有哪些_有序集合_15

  1. info replication 打印主从复制的相关信息

java redis原子操作 redis原子操作有哪些_Redis_16

  1. salveof <ip> <port> 成为主从复制的相关信息

java redis原子操作 redis原子操作有哪些_Redis_17

java redis原子操作 redis原子操作有哪些_java redis原子操作_18

3、一主二从模式

java redis原子操作 redis原子操作有哪些_java redis原子操作_19

复制原理:

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

java redis原子操作 redis原子操作有哪些_Redis_20

4、薪火相传模式演示

  1. 上一个 slave 可以是下一个 slave 的 Master,slave 同样可以接收其他的 slaves 的接收和同步请求,那么该slave 作为链条中下一个的 master, 可以有效减轻 master 的写压力,去同步化降低风险。
    中途变更转向:会清除之前的数据,重新建立拷贝最新的
    风险是一旦某个 slave 宕机,后面的 slave 都没法备份
  2. 反客为主(小弟上位)

当一个 master 宕机后,后面的 slave 可以立即升为 master, 其后面的 slave 不用做任何修改。用 slave no one 将从机边为主机。

  1. 哨兵模式 sentine(推荐大哥)
    反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。

配置哨兵

  • 调整为一主二从模式
  • 自定义的/myRedis 目录下新建 sentine.conf 文件
  • 在配置文件中填写内容
    sentinel monitor mymaster 127.0.0.1 6379 1
    其中 mymaster为监控对象起的服务器名称(随意起), 1为 至少有多少个哨兵同意迁移的数量。
  • 启动哨兵
    执行 redis-sentinel /myRedis/sentinel.conf

java redis原子操作 redis原子操作有哪些_有序集合_21

5、故障恢复

java redis原子操作 redis原子操作有哪些_java redis原子操作_22

七、Redis 集群

1、集群

  1. Redis 集群 实现了对 Redis 的水平扩容,即启动 N 个 redis 节点,将整个数据库分布式存储在这个 N 个节点中, 每个节点存储总数据的1/N。
  2. Redis 集群通过分区(partiton)来提供一定程度的可用性(availability ): 即使集群中有部分节点失效或者无法进行通信,集群也可以继续处理命令请求。

2、安装 ruby 环境

能上网

  • 执行yum install ruby
  • 执行 yum install rubygems

不能上网

  • cd /run/media/root/CentOS 7 x86_64/Packages 获取如下 rpm 包

注意

因为redis集群需要使用2.3.0及以上版本,而Linux 系统自带的是2.0.0,需要更新一下,才能启动

方法:换yum源安装

yum install centos-release-scl-rh    //会在/etc/yum.repos.d/目录下多出一个CentOS-SCLo-scl-rh.repo源
 
yum install rh-ruby23  -y    //直接yum安装即可  
 
scl  enable  rh-ruby23 bash    //必要一步
 
ruby -v    //查看安装版本

使用:gem install redis

java redis原子操作 redis原子操作有哪些_Redis_23

3、准备6个 Redis实例

  1. 准备 6 个实例 6379,6380,6381,6389,6390,6391

java redis原子操作 redis原子操作有哪些_有序集合_24

拷贝多个 redis.conf 文件
开启 daemonize yes
Pid 文件名字
指定端口
Log 文件名字
Dump.rdb 名字
Appendonly 关掉或者换名字

再加入如下配置
cluster-enabled yes 打开集群模式
cluster-config-file nodes-端口号.conf 设定节点配置文件名
cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行
主从切换

include /opt/myRedis/redis.conf
pidfile /var/run/redis6379.pid
port 6379
dbfilename dump6379.rdb
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000

4、合体

  1. 将 6 个实例全部启动, nodes-端口号.conf 文件都生成正常

java redis原子操作 redis原子操作有哪些_Redis_25

2.合体

  • 进入到 cd /opt/redis-3.2.5/src
  • 执行

./redis-trib.rb create --replicas 1 192.168.64.129:6379 192.168.64.129:6380 192.168.64.129:6381 192.168.64.129:6389 192.168.64.129:6390 192.168.64.129:6391

注意: IP 地址修改为当前服务器的地址,端口号为每个 Redis 实例对应的端口号

5、集群操作

  1. 以集群的方式进入客户端
redis-cli -c -p 端口号
  1. 通过 cluster nodes 命令查看集群信息

java redis原子操作 redis原子操作有哪些_java redis原子操作_26

  1. redis cluster 如何分配这六个节点。一个集群至少要有三个主节点。选项 --replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。分配原则尽量保证每个主数据库运行在不同的 IP 地址,每个从库和主库不在一个 IP 地址上。
  2. slots :一个 Redis 集群包含 16384 个插槽( hash slot), 数据库中的每个键都属于这16384 个插槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
  • 集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点,
    其中:
  • 节点 A 负责处理 0 号至 5500 号插槽。
  • 节点 B 负责处理 5501 号至 11000 号插槽。
  • 节点 C 负责处理 11001 号至 16383 号插槽
  1. 在集群中录入值
  • 在 redis-cli 每次录入、查询键值, redis 都会计算出该 key 应该送往的插槽,如果不是该客户端对应服务器的插槽, redis 会报错,并告知应前往的 redis 实例地址和端口.
  • redis-cli 客户端提供了 – c 参数实现自动重定向。如 redis-cli -c – p 6379 登入后,再录入、查询键值对可以自动重定向。
  • 不在一个 slot 下的键值,是不能使用 mget,mset 等多键操作。
  • 可以通过{}来定义组的概念,从而使 key 中{}内相同内容的键值对放到一个 slot 中去 。

java redis原子操作 redis原子操作有哪些_数据_27

  • 不在一个 slot 下的键值,是不能使用 mget,mset 等多键操作。
  • 可以通过{}来定义组的概念,从而使 key 中{}内相同内容的键值对放到一个 slot 中去 。
  1. 查询集群中的值
  • CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。

java redis原子操作 redis原子操作有哪些_数据_28

  • CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量

java redis原子操作 redis原子操作有哪些_Redis_29

  • CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键

java redis原子操作 redis原子操作有哪些_java redis原子操作_30

6、集群的 Jedis 开发

public class JedisClusterTest {
	public static void main(String[] args) {
		Set<HostAndPort> set =new HashSet<HostAndPort>();
		set.add(new HostAndPort("192.168.64.129",6379));
		JedisCluster jedisCluster=new JedisCluster(set);
		jedisCluster.set("k1", "v1");
		System.out.println(jedisCluster.get("k1"));
	}
}

7、Redis 集群的优缺点

  • 优点
  1. 实现扩容
  2. 分摊压力
  3. 无中心配置相对简单
  • 缺点
  1. 多键操作是不被支持的
  2. 多键的 Redis 事务是不被支持的。 lua 脚本不被支持。
  3. 由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片 的方案想要迁移至 redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。

STER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键

[外链图片转存中…(img-GJ5kR9U1-1599715166537)]

6、集群的 Jedis 开发

public class JedisClusterTest {
	public static void main(String[] args) {
		Set<HostAndPort> set =new HashSet<HostAndPort>();
		set.add(new HostAndPort("192.168.64.129",6379));
		JedisCluster jedisCluster=new JedisCluster(set);
		jedisCluster.set("k1", "v1");
		System.out.println(jedisCluster.get("k1"));
	}
}

7、Redis 集群的优缺点

  • 优点
  1. 实现扩容
  2. 分摊压力
  3. 无中心配置相对简单
  • 缺点
  1. 多键操作是不被支持的
  2. 多键的 Redis 事务是不被支持的。 lua 脚本不被支持。
  3. 由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片 的方案想要迁移至 redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。