Redis 安装、命令、三种集群(主从模式、哨兵模式、cluster模式)详细讲解、java使用Redis、springboot集成redis一文打尽~
Remote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value存储系统,是跨平台的非关系型数据库。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
可以查看我的另外一篇博客《Redis安装配置》
1)Redis客户端
# 连接本地redis
$ redis-cli
127.0.0.1:6379>
# 连接远程redis
$ redis-cli -h host -p port -a password
键(key)
127.0.0.1:6379> set name guoguo
OK
127.0.0.1:6379> dump name # 序列化给定 key ,并返回被序列化的值
"\x00\x06guoguo\t\x00\x1fil\x1d`\xa1\x84\xa9"
127.0.0.1:6379> exists name # 检查给定 key 是否存在
(integer) 1
127.0.0.1:6379> exists age
(integer) 0
127.0.0.1:6379> expire name 100 # 为给定 key 设置过期时间,以秒计
(integer) 1
127.0.0.1:6379> ttl name # 以秒为单位,返回给定 key 的剩余生存时间
(integer) 96
127.0.0.1:6379> del name # 该命令用于在 key 存在时删除 key
(integer) 1
详细的api命令请查看《Redis 命令说明文档》
字符串(String)
127.0.0.1:6379> set name xa87guoGuo # 设置key的值
OK
127.0.0.1:6379> get name # 获取key的值
"xa87guoGuo"
127.0.0.1:6379> getrange name 3 8 # 返回 key中字符串值的子字符
"7guoGu"
127.0.0.1:6379> strlen name # 返回 key 所储存的字符串值的长度
(integer) 10
127.0.0.1:6379> mset k1 v1 k2 v2 # 同时设置一个或多个 key-value 对
OK
127.0.0.1:6379> mget k1 k2 # 获取所有给定 key 的值
1) "v1"
2) "v2"
127.0.0.1:6379> setex k3 100 v3 # 将值 value(v3) 关联到 key(k3) ,并将 key 的过期时间设为 seconds(100) (以秒为单位)
OK
详细的api命令请查看《Redis 命令说明文档》
哈希(Hash)
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(4294967295, 40多亿)
127.0.0.1:6379> hmset person1 name "zhangsan" age 20 sex 1 address "shanxi xi'an" # 同时将多个 field-value (域-值)对设置到哈希表 key 中
OK
127.0.0.1:6379> hgetall person1 # 获取在哈希表中指定 key 的所有字段和值
1) "name"
2) "zhangsan"
3) "age"
4) "20"
5) "sex"
6) "1"
7) "address"
8) "shanxi xi'an"
127.0.0.1:6379> hexists person1 name # 查看哈希表 key 中,指定的字段是否存在
(integer) 1
127.0.0.1:6379> hexists person1 p
(integer) 0
127.0.0.1:6379> hkeys person1 # 获取所有哈希表中的字段
1) "name"
2) "age"
3) "sex"
4) "address"
127.0.0.1:6379> hmget person1 name
1) "zhangsan"
127.0.0.1:6379> hvals person1 # 获取哈希表中所有值
1) "zhangsan"
2) "20"
3) "1"
4) "shanxi xi'an"
详细的api命令请查看《Redis 命令说明文档》
列表(List)
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)
127.0.0.1:6379> lpush lkey redis mongodb mysql es # 将多个值插入到列表头部
(integer) 4
127.0.0.1:6379> llen lkey # 获取列表长度
(integer) 4
127.0.0.1:6379> lrange lkey 0 -1 # 获取列表指定范围内的元素
1) "es"
2) "mysql"
3) "mongodb"
4) "redis"
127.0.0.1:6379> lpop lkey # 移出并获取列表的第一个元素
"es"
127.0.0.1:6379> lpush lkey abc # 将一个值插入到已存在的列表头部
(integer) 4
127.0.0.1:6379> lrange lkey 0 -1
1) "abc"
2) "mysql"
3) "mongodb"
4) "redis"
127.0.0.1:6379> rpop lkey # 移除列表的最后一个元素,返回值为移除的元素
"redis"
127.0.0.1:6379> rpush lkey guoguo # 在列表最后添加一个或多个值
(integer) 4
127.0.0.1:6379> lrange lkey 0 -1
1) "abc"
2) "mysql"
3) "mongodb"
4) "guoguo"
详细的api命令请查看《Redis 命令说明文档》
集合(Set)
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
127.0.0.1:6379> sadd skey redis mongodb mysql es # 向集合添加一个或多个成员
(integer) 4
127.0.0.1:6379> sadd skey mysql
(integer) 0
127.0.0.1:6379> smembers skey # 返回集合中的所有成员
1) "redis"
2) "es"
3) "mysql"
4) "mongodb"
127.0.0.1:6379> sadd db mysql oracle sqlserver
(integer) 3
127.0.0.1:6379> sdiff skey db # 返回第一个集合与其他集合之间的差异
1) "redis"
2) "es"
3) "mongodb"
127.0.0.1:6379> sinter skey db # 返回给定所有集合的交集
1) "mysql"
127.0.0.1:6379> sunion skey db # 返回所有给定集合的并集
1) "mongodb"
2) "redis"
3) "mysql"
4) "es"
5) "oracle"
6) "sqlserver"
详细的api命令请查看《Redis 命令说明文档》
有序集合(sorted set)
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。
Redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。
Redis 有序集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
127.0.0.1:6379> zadd dbkey 1 redis 3 mongodb 5 es 2 mysql # 向有序集合添加一个或多个成员,或者更新已存在成员的分数
(integer) 4
127.0.0.1:6379> zrange dbkey 0 -1 # 通过索引区间返回有序集合指定区间内的成员
1) "redis"
2) "mysql"
3) "mongodb"
4) "es"
127.0.0.1:6379> zrange dbkey 0 -1 withscores # 通过索引区间返回有序集合指定区间内的成员
1) "redis"
2) "1"
3) "mysql"
4) "2"
5) "mongodb"
6) "3"
7) "es"
8) "5"
127.0.0.1:6379> zcard dbkey # 获取有序集合的成员数
(integer) 4
127.0.0.1:6379> zrank dbkey redis # 返回有序集合中指定成员的索引
(integer) 0
127.0.0.1:6379> zscore dbkey redis # 返回有序集中,成员的分数值
"1"
127.0.0.1:6379> zadd dbkey1 10 oracle 11 sqlserver
(integer) 2
127.0.0.1:6379> zunionstore alldb 2 dbkey dbkey1 # 计算给定的一个或多个有序集的并集,并存储在新的 key 中
(integer) 6
127.0.0.1:6379> zrange alldb 0 -1
1) "redis"
2) "mysql"
3) "mongodb"
4) "es"
5) "oracle"
6) "sqlserver"
详细的api命令请查看《Redis 命令说明文档》
有两个redis服务:
master (192.168.0.72:6379)
slave (192.168.0.72:6379)
要想实现主从集群,只需要修改一下slave的redis.conf文件
# replicaof
replicaof 192.168.0.72 6379
然后重启slave服务,这样就把主从集群建立好了。
看一下测试的效果:
主从模式有个缺点,若master宕机需要手动配置slave转为master。为了解决高可用的问题出现了哨兵模式。
有三个redis服务
master(192.168.0.72:6379)
slave1 (192.168.0.72:6379)
slave 2(192.168.0.72:6379)
master(192.168.0.72)服务开启密码并关闭保护模式
protected-mode no
requirepass 123456
配置哨兵,在redis的安装目录找到sentinel.conf 修改如下:
protected-mode yes
bind 192.168.0.72
# bind值为各个sentinel 所在的服务器的ip
# bind 192.168.0.73
# bind 192.168.0.52
daemonize yes
pidfile "/var/run/sentinel/redis-sentinel.pid"
logfile "/var/log/redis/redis-sentinel.log"
port 26379
dir "/var/lib/redis"
sentinel myid f392d8a65d028eb65b1baa94d4f981ab539a3ceb
sentinel monitor mymaster 192.168.0.72 6379 2
sentinel auth-pass mymaster 123456
slave1 与 slave2 的redis.conf 修改和主从模式一样
replicaof 192.168.0.72 6379
# 这个是master 的密码
masterauth 123456
服务启动的顺序为先master后slave
启动命令
service redis start
service redis-sentinel start
哨兵模式在master故障后自动选举新的master。但是不能动态扩充。所以在3.x后提出了cluster集群模式
1)安装Redis
准备两个服务器,每个服务器上运行三个redis实例端口分别为7001,7002,7002
yum install gcc-c++
wget https://download.redis.io/releases/redis-6.2.1.tar.gz
tar xzf redis-6.2.1.tar.gz
cd redis-6.2.1
make
make install PREFIX=/usr/loacl/redis-cluster
cp redis.conf /usr/local/redis-cluster/
# redis 5.0 之前版本需要
cp src/redis-trib.rb /usr/local/redis-cluster/
cd /usr/local/redis-cluster/
mv bin redis0
cp -r reids0 reids1
cp -r reids0 reids2
修改redis.conf
daemonize yes #后台启动
port 7001 #修改端口号,从7001到7003
cluster-enabled yes #开启cluster,去掉注释
cluster-config-file nodes.conf # 节点配置文件
cluster-node-timeout 15000
appendonly yes #开启aof
将修改好的redis.conf 分别拷贝到redis0,redis1,redis2
2)Ruby环境(Redis 5.0之前版本需要)
yum -y install ruby rubygems
# 升级一下gem版本
gem update --system
gem -v
# 替换repository
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
gem install redis -v 3.3.5
3)启动redis
cd /usr/local/redis-cluster/redis0
./redis-server redis.conf
cd ../redis1
./redis-server redis.conf
cd ../redis2
./redis-server redis.conf
4)创建集群
# 创建集群之前开启相应端口,或者关闭服务器防火墙
firewall-cmd --add-port=7001/tcp --permanent
firewall-cmd --add-port=17001/tcp --permanent
firewall-cmd --reload
# 若Redis的端口为7001 那对应的集群总线端口为17001。这两个端口都也开启,否则在创建集群时会一直等待。
# Redis5.0之前版本启动方式
cd /usr/local/redis-cluster/
./redis-trib.rb create --replicas 1 \
192.168.0.75:7001 \
192.168.0.75:7002 \
192.168.0.75:7003 \
192.168.0.76:7004 \
192.168.0.76:7005 \
192.168.0.76:7006
# Redis5.0之后版本的启动方式
/usr/local/redis-cluster/redis0/redis-cli --cluster create \
192.168.0.75:7001 \
192.168.0.75:7002 \
192.168.0.75:7003 \
192.168.0.76:7004 \
192.168.0.76:7005 \
192.168.0.76:7006 --cluster-replicas 1
5)测试连接
redis-cli -h 192.168.0.75 -c -p 7001
Jedis 是老牌的 Redis 的 Java 实现客户端,提供了比较全面的 Redis 命令的支持
优点:
- 支持全面的 Redis 操作特性(可以理解为API比较全面);
缺点:
- 使用阻塞的 I/O,且其方法调用都是同步的,程序流需要等到sockets 处理完 I/O 才能执行,不支持异步;
- Jedis 客户端实例不是线程安全的,所以需要通过连接池来使用 Jedis;
Lettuce是一种可扩展的线程安全的 Redis 客户端,支持异步模式
优点:
- 支持同步异步通信模式;
- Lettuce 的 API 是线程安全的,如果不是执行阻塞和事务操作,如BLPOP和MULTI/EXEC,多个线程就可以共享一个连接;
Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的 Java 常用对象,还提供了许多分布式服务
优点:
- 使用者对 Redis 的关注分离,可以类比 Spring 框架,这些框架搭建了应用程序的基础框架和功能,提升开发效率,让开发者有更多的时间来关注业务逻辑;
- 提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列等;
缺点:
- Redisson 对字符串的操作支持比较差