Redis的事务,持久化,主从,哨兵,集群以及常见问题
程序员文章站
2022-06-17 21:12:23
RedisRedis的AUTH# 设置Redis连接密码requirepass 密码后期部署Redis上线时必定要设置密码在redis.conf配置文件中追加一个属性 requirepass 密码在Redis启动后,在容器中的redis-cli中执行config set requirepass 密码(重启后无效,基本不用)客户端连接时,如何指定密码:redis-cli中,采用auth命令,在执行读写操作前,先执行auth密码图形化界面直接连接验证java操作时:单独在执行的Je...
Redis
Redis的AUTH
# 设置Redis连接密码
requirepass 密码
后期部署Redis上线时必定要设置密码
- 在redis.conf配置文件中追加一个属性 requirepass 密码
- 在Redis启动后,在容器中的redis-cli中执行config set requirepass 密码(重启后无效,基本不用)
客户端连接时,如何指定密码:- redis-cli中,采用auth命令,在执行读写操作前,先执行auth密码
- 图形化界面直接连接验证
- java操作时:
- 单独在执行的Jedis的方法前,先执行jedis.auth(密码)
- 在使用JedisPool时,在构造方法中,追加密码操作即可。
Redis的事务
Redis的事务不同于传统的关系型数据库的事务
- 一次Redis的事务操作,该成功的成功,该失败的失败。
- Redis的事务和watch监听机制配合使用:先执行watch指定监听的key,如果在一次事务操作中,监听的key被修改了,当前事务自动取消。
- 使用命令:
- mutli:开启事务
- exec:执行事务
- discard:取消事务
- watch key [key…]:监听指定的key
- unwatch:取消全部监听的key
Redis的持久化机制
在/usr/local/docker_redis/conf/redis.conf文件中
# 开启RDB持久化,指定持久化文件存放的路径 dir /data/ dbfilename redis.rdb # 指定Redis的RDB持久化时机 save 10 1 #---------------------------------------------- # 开启AOF持久化 appendonly yes # 指定AOF文件的名称 appendfilename "redis.aof" # 指定AOF持久化时机 appendfsync everysec
RDB:
- 基于二进制文件持久化数据,存储速度块,占用空间小,传输速度块,恢复数据速度块。
- 持久化时机:
- 在指定时间内,执行了多少次写操作,就执行RDB持久化。
- after 900 sec (15 min) if at least 1 key changed
- save 900 1
- RDB持久化机制相对不安全,可能会丢失数据。
AOF:
- 基于日志文件持久化数据,数据更安全不易丢失,日志文件可以看懂。
- 持久化时机:
- 每执行一次命令就执行AOF持久化:appendfsync always
- 每秒执行一次AOF持久化:appendfsync sec (默认的,也是推荐的)
- 根据系统环境,一段时间执行一次,不可控:appendfsync no
- AOF文件在内容特别多时,恢复数据速度相对RDB更慢,而且占用空间大。
RDB和AOF的注意事项- Redis官方推荐同时开启RDB和AOF,不但保证数据的安全,也可以提升数据传输,恢复等等的效率。
- 如果同时开启了RDB和AOF,在恢复数据时,优先使用AOF文件。
- 如果同时开启了RDB和AOF,在RDB执行持久化时,RDB文件会被AOF文件覆盖掉。
Redis 的主从架构
主从架构可以帮助我们提升Redis读取数据的能力,通过搭建多个slave从节点,来提升读写瓶颈。
- 主节点可以进行读写操作,从节点只能执行读操作。
- 从节点不会相互通讯,只连接Master主节点。
- 从节点的数据都是从master同步过来的。
- 如果主从架构中matser节点宕机,整个Redis服务将不提供写操作。
实现主从架构配置:
- 只需要让Slave从节点链接上Master集合。
- 在/usr/local/docker_redis_master-slave/conf中加入 replicaof masterip masterport
Redis的主从+哨兵
由于主从架构存在单点故障问题,当Master节点宕机后,主从架构将无法提供写操作,可以在主从架构的基础上,添加哨兵,在Master宕机后,哨兵可以在多个Slave中选举出以为全新的Master节点。
- 准备sentinel配置文件:
- 守护进程,保证哨兵可以后台启动:daemonize yes
- 告诉哨兵Master节点信息:sentinel monitor mymaster redis1 6379 2
指定哨兵多久检测一下,主从架构的健康情况:sentinel down-after-milliseconds mymaster 10000
-正常的启动Redis的主从架构容器- 分别的进入Master和Slave容器,并分别启动哨兵redis-sentinel sentinel1.conf,指定编写好的配置文件
修改Redis服务的配置文件权限:chmod -R 777 conf- 直接关闭Master容器,查看slave节点的日志:CONFIG REWRITE …
- 发现Redis的配置文件全部被哨兵重写。
Redis集群
Redis集群介绍
主从+哨兵的架构,无法提升存储数据能力的上限,也无法分担写数据的压力。而Redis集群时可以做到的。
- Redis集群是无中心的。
- 每一个Redis节点之间有一个ping-pang机制,每个节点之间都可以相互通讯。
- 由于Redis集群带有投票机制,集群的节点树应该时奇数个。
- Redis集群中默认分配16384个哈希槽,并且由不同的Redis节点去维护,当客户端写数据时,会先将key进行crc16运算,并且将最终得到的结果对16384取余数,得到的结果是0~16383之间的数字,直接根据结果存储到不同的Redis节点,从而提升存储能力,以及分担写数据的压力。
- 每个Redis集群中的节点,至少要由一个从节点,避免单点故障。
- 集群中的从节点,不会分担读数据的压力,想提升读数据的能力,需要单独自己搭建主从。
- 在Redis集群超过半数节点不可用时,集群才会瘫痪。
搭建Redis集群
1、准备6个Redis的服务
version: "3.1"
services:
redis1:
image: 10.0.134.175:5000/redis:5.0.9
restart: always
container_name: redis1
environment:
- TZ=Asia/Shanghai
ports:
- 7001:7001
- 17001:17001
volumes:
- ./conf/redis1.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis2:
image: 10.0.134.175:5000/redis:5.0.9
restart: always
container_name: redis2
environment:
- TZ=Asia/Shanghai
ports:
- 7002:7002
- 17002:17002
volumes:
- ./conf/redis2.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis3:
image: 10.0.134.175:5000/redis:5.0.9
restart: always
container_name: redis3
environment:
- TZ=Asia/Shanghai
ports:
- 7003:7003
- 17003:17003
volumes:
- ./conf/redis3.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis4:
image: 10.0.134.175:5000/redis:5.0.9
restart: always
container_name: redis4
environment:
- TZ=Asia/Shanghai
ports:
- 7004:7004
- 17004:17004
volumes:
- ./conf/redis4.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis5:
image: 10.0.134.175:5000/redis:5.0.9
restart: always
container_name: redis5
environment:
- TZ=Asia/Shanghai
ports:
- 7005:7005
- 17005:17005
volumes:
- ./conf/redis5.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
redis6:
image: 10.0.134.175:5000/redis:5.0.9
restart: always
container_name: redis6
environment:
- TZ=Asia/Shanghai
ports:
- 7006:7006
- 17006:17006
volumes:
- ./conf/redis6.conf:/usr/local/redis/redis.conf
command: ["redis-server","/usr/local/redis/redis.conf"]
2、准备6个Redis的配置文件
# 0. 指定端口号
port 7001
# 1. 开启Redis集群。 832行。
cluster-enabled yes
# 2. 指定Redis集群节点信息的文件名称 840行。
cluster-config-file nodes-6379.conf
# 3. Docker搭建Redis集群,指定 ip,port,bus
cluster-announce-ip 10.0.131.232
cluster-announce-port 7001
cluster-announce-bus-port 17001
.....
3、启动6个Redis服务
4、进入到任意一个Redis服务的容器中,执行命令
redis-cli --cluster create ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6 --cluster-repalicas 1
5、集群启动成功后,使用redis-cli连接
redis-cli -p 端口号 -c
Java连接Redis集群
@Test
// Keys操作,在原生的JedisCluster中,无法使用,需要自己封装.
public void test(){
Set<HostAndPort> nodes = new HashSet<>();
HostAndPort h1 = new HostAndPort("10.0.131.232",7001);
HostAndPort h2 = new HostAndPort("10.0.131.232",7002);
HostAndPort h3 = new HostAndPort("10.0.131.232",7003);
HostAndPort h4 = new HostAndPort("10.0.131.232",7004);
HostAndPort h5 = new HostAndPort("10.0.131.232",7005);
HostAndPort h6 = new HostAndPort("10.0.131.232",7006);
nodes.add(h1);
nodes.add(h2);
nodes.add(h3);
nodes.add(h4);
nodes.add(h5);
nodes.add(h6);
JedisCluster jedisCluster = new JedisCluster(nodes);
Map<String, JedisPool> clusterNodes = jedisCluster.getClusterNodes();
Set<Map.Entry<String, JedisPool>> entries = clusterNodes.entrySet();
Set<String> allKeys = new HashSet<>();
for (Map.Entry<String, JedisPool> entry : entries) {
JedisPool pool = entry.getValue();
Jedis jedis = pool.getResource();
Set<String> keys = jedis.keys("*");
allKeys.addAll(keys);
}
System.out.println(allKeys);
}
Redis常见问题(重点|面试题)
删除策略
- 定期删除,默认在100ms中,随机抽取出三个设置了生存时间的key,如果生存时间已经到了,会删除当前key。
- 惰性删除,在你查询一个key时,先查看当前key的生存时间是否已经到了,如果到了,直接删除当前key,并给用户返回一个null。
淘汰策略
- volatile-lru:在设置了过期时间的key中,删除最近最少使用的key。
- allkeys-lru:在全部的key中,删除最近最少使用的key。
- volatile-lfu:在设置了过期时间的key中,删除最近最少频次使用的key。
- allkeys-lfu:在全部的key中,删除最近最少频次使用的key。
- volatile-random:在设置了过期时间的key中,随机删除key。
- allkeys-random:在全部的key中,随机删除key。
- volatile-ttl:删除剩余生存时间最少的key。
- noeviction:不删除key,直接报错。
缓存的各种问题
本文地址:https://blog.csdn.net/ya_yongng/article/details/107324206