赞
踩
Redis 本身支持持久化,有三种方式
定义:
在 **默认情况下,**redis将内存数据库快照保存在名字为 dump.rdb 文件中 【将内存拍照,压缩成二进制存储dump.rdb】
开启:
# 通过配置文件中
## 在time时间内,数据库有count个key被改动,触发一次save,生成dump.rdb文件
save time count
## 配置数据文件路径,这里的dir放备份文件RDB和AOF
dir [path]
## 配置备份文件名称
dbfilename dump-6379.rdb
配置完成后,通过命令可以主动生成 RDB 快照
怎么恢复?
redis在重启的时候会自动恢复数据
优点
定义:
append-only file,AOF持久化将修改的每一条指令记录到文件appendonly.aof 【先写入os cache,每隔一段时间fsync到磁盘】
开启:
# 在配置文件中
## appendonly值修改为yes 开启AOF功能
appendonly yes
## 备份文件名称
appendfilename appendonly.aof
## 模式选择 内存刷入磁盘的时间 [总是,每秒,不刷入]
appendfsync [always , everysec , no]
配置完成后,AOF功能会开启
重写指令:
bgrewriteaof
重写AOF中的垃圾命令,【没必要的自增命令等】 减少磁盘空间占用
# aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就快,重写的意义不大
auto‐aof‐rewrite‐min‐size 64mb
# aof文件自上一次重写后文件大小增长了100%则再次触发重写
auto‐aof‐rewrite‐percentage 100
原因:
所以可以采用混合持久化,它是AOF的升级版
开启
# 配置
## 开启混合持久化
aof‐use‐rdb‐preamble yes
配置完成后
**AOF在重写时,**不再是简单的将 内存数据 转换为RESP命令写入 AOF 文件,
# 架构搭建,配置从节点步骤 # 1、复制一份redis.conf文件 # 2、将相关配置修改为如下值: port 6380 pidfile /var/run/redis_6380.pid # 把pid进程号写入pidfile配置的文件 logfile /usr/local/redis/log/6380.log dir /usr/local/redis/data/6380 # 指定数据存放目录 # 需要注释掉bind # bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可) # 3、配置主从复制 replicaof 192.168.0.60 6379 # 从本机6379的redis实例复制数据,Redis 5.0之前使用slaveof replica‐read‐only yes # 配置从节点只读 # 4、启动从节点 redis‐server redis.conf # 5、连接从节点 redis‐cli ‐p 6380 # 6、测试在6379实例上写数据,6380实例是否能及时同步新修改数据 # 7、可以自己再配置一个6381的从节点
有一下两种方式
流程:
注意:
如果master收到多个slave并发请求,只会进行一次持久化,并将rdb 发送给多个并发连接的slave
当master和slave断开重连后,支持部分数据复制的命令PSYNC去同步master的数据。【断点续传】
流程:
定义:
如果有很多从节点,多个从节点同时复制主节点导致主节点压力过大,可以做如下架构优化
定义:
sentinel哨兵是特殊的redis服务,主要用来 监控redis实例节点
客户端通过连接sentinel集群,来连接redis集群,因为sentinel集群中的节点始终指向redis集群中的master节点,当master节点宕机后,sentinel会选举一个新的master节点
流程:
# 1、复制一份sentinel.conf文件 cp sentinel.conf sentinel‐26379.conf # 2、将相关配置修改为如下值: port 26379 daemonize yes pidfile "/var/run/redis‐sentinel‐26379.pid" logfile "26379.log" dir "/usr/local/redis‐5.0.3/data" # sentinel monitor <master‐redis‐name> <master‐redis‐ip> <master‐redis‐port> <quorum> # quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 +1),master才算真正失效 【半数以上选举】 sentinel monitor mymaster 47.107.82.29 6379 2 # mymaster这个名字随便取,客户端访问时会用到,关闭防火墙 # 3、启动sentinel哨兵实例 src/redis‐sentinel sentinel‐26379.conf # 4、查看sentinel的info信息 src/redis‐cli ‐p 26379 127.0.0.1:26379>info # 可以看到Sentinel的info里已经识别出了redis的主从 # 5、可以自己再配置两个sentinel,端口26380和26381,注意上述配置文件里的对应数字都要修改
当master宕机后,slave要通过选举才能成为新的master
当一个master服务器被某个sentinel定为下线后
可以只有一个sentinel,不过为了高可用,一般至少配置三个
定义:
客户端可以一次性发送多个请求而不等待服务器的响应,等所有命令发送完后再一次性读取响应,降低网络传输开销
管道执行多条命令是通过pipeline方式打包命令发送,redis处理完所有命令前先缓存所有命令的处理结果,但不保证全都成功执行。
注意,不要在Lua脚本中出现死循环或者耗时的运算,否则redis会阻塞,单线程执行脚本,管道不会阻塞redis
String类型结构 | |
---|---|
Redis | RedisTemplate rt |
set key value | rt.opsForValue().set(“key”,“value”) |
get key | rt.opsForValue().get(“key”) |
del key | rt.delete(“key”) |
strlen key | rt.opsForValue().size(“key”) |
getset key value | rt.opsForValue().getAndSet(“key”,“value”) |
getrange key start end | rt.opsForValue().get(“key”,start,end) |
append key value | rt.opsForValue().append(“key”,“value”) |
Hash结构 | |
hmset key field1 value1 field2 value2… | rt.opsForHash().putAll(“key”,map) //map是一个集合对象 |
hset key field value | rt.opsForHash().put(“key”,“field”,“value”) |
hexists key field | rt.opsForHash().hasKey(“key”,“field”) |
hgetall key | rt.opsForHash().entries(“key”) //返回Map对象 |
hvals key | rt.opsForHash().values(“key”) //返回List对象 |
hkeys key | rt.opsForHash().keys(“key”) //返回List对象 |
hmget key field1 field2… | rt.opsForHash().multiGet(“key”,keyList) |
hsetnx key field value | rt.opsForHash().putIfAbsent(“key”,“field”,“value” |
hdel key field1 field2 | rt.opsForHash().delete(“key”,“field1”,“field2”) |
hget key field | rt.opsForHash().get(“key”,“field”) |
List结构 | |
lpush list node1 node2 node3… | rt.opsForList().leftPush(“list”,“node”) |
rt.opsForList().leftPushAll(“list”,list) //list是集合对象 | |
rpush list node1 node2 node3… | rt.opsForList().rightPush(“list”,“node”) |
rt.opsForList().rightPushAll(“list”,list) //list是集合对象 | |
lindex key index | rt.opsForList().index(“list”, index) |
llen key | rt.opsForList().size(“key”) |
lpop key | rt.opsForList().leftPop(“key”) |
rpop key | rt.opsForList().rightPop(“key”) |
lpushx list node | rt.opsForList().leftPushIfPresent(“list”,“node”) |
rpushx list node | rt.opsForList().rightPushIfPresent(“list”,“node”) |
lrange list start end | rt.opsForList().range(“list”,start,end) |
lrem list count value | rt.opsForList().remove(“list”,count,“value”) |
lset key index value | rt.opsForList().set(“list”,index,“value”) |
Set结构 | |
sadd key member1 member2… | rt.boundSetOps(“key”).add(“member1”,“member2”,…) |
rt.opsForSet().add(“key”, set) //set是一个集合对象 | |
scard key | rt.opsForSet().size(“key”) |
sidff key1 key2 | rt.opsForSet().difference(“key1”,“key2”) //返回一个集合对象 |
sinter key1 key2 | rt.opsForSet().intersect(“key1”,“key2”)//同上 |
sunion key1 key2 | rt.opsForSet().union(“key1”,“key2”)//同上 |
sdiffstore des key1 key2 | rt.opsForSet().differenceAndStore(“key1”,“key2”,“des”) |
sinter des key1 key2 | rt.opsForSet().intersectAndStore(“key1”,“key2”,“des”) |
sunionstore des key1 key2 | rt.opsForSet().unionAndStore(“key1”,“key2”,“des”) |
sismember key member | rt.opsForSet().isMember(“key”,“member”) |
smembers key | rt.opsForSet().members(“key”) |
spop key | rt.opsForSet().pop(“key”) |
srandmember key count | rt.opsForSet().randomMember(“key”,count) |
srem key member1 member2… | rt.opsForSet().remove(“key”,“member1”,“member2”,…) |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。