redis
2022-04-04 17:43:18 27 举报
AI智能生成
redis
作者其他创作
大纲/内容
将Redis内存中的数据保存到磁盘上,一般线上redis内存都是以G为单位的,所以该操作会影响Redis性能
save 900 1 900秒内发生一次save 300 10 300秒内发生10次save 60 10000 60秒内发生10000dbfilename dump.rdb 快照名dir ./ 快照路径
登陆状态下:bgsave
未登录状态下:./redis-cli bgsave
会阻塞用户请求处理的性能
save
后台fork一个进程,来做持久化操作,不会影响用户请求处理。注意:COW技术
bgsave
手动快照
恢复速度快,文件体积小,但是容易丢数据
RDB快照:snapshotting
appendonly yes 开启appendfilename \"appendonly.aof\" 文件名# appendfsync always 每次操作都存储(最多只丢一条数据)appendfsync everysec 每秒存储一次(最多丢一秒的数据)# appendfsync no
AOF中存储的是一条条命令,恢复时是重新执行这些命令
AOF文件里可能有太多没用指令,所以AOF会定期根据内存的最新数据生成aof文件
auto‐aof‐rewrite‐min‐size 64mb//aof文件至少要达到64M才会自动重写
auto‐aof‐rewrite‐percentage 100//aof文件自上一次重写后文件大小增长了100%则再次触发重写
AOF重写频率
AOF重写
恢复速度慢,文件体积大,但是可以根据策略决定数据安全性
Redis启动后,默认用AOF恢复数据,因为AOF数据更全
AOF追加:appendonly
Redis混合持久化开关:aof-use-rdb-preamble yes
AOF重写时不在单纯地将内存数据转换为命令存储在AOF中,而是将这一刻之前的数据做RDB快照处理,并且将RDB快照内容和增量的AOF修改数据命令存在一起,都写入新的AOF文件。Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。
Redis4.0引入混合持久化
持久化
在从服务器中配置slaveof 192.168.1.1 6379masterauth <password>
http://doc.redisfans.com/topic/replication.html
配置主服务器地址:slaveof 192.168.1.1 6379
从服务器默认只读,设置从服务器只读:slave-read-only yes
如果主服务器设置了密码,那么需要配置密码来访问:masterauth <password>
从服务器至少达到N个才让从服务器执行写操作:min-slaves-to-write N
从服务器延迟低于M秒才向从服务器发送写命令:min-slaves-max-lag M
配置
设置主服务器地址:SLAVEOF 192.168.1.1 10086
设置只读: CONFIG SET
设置主服务器访问密码:config set masterauth <password>
命令
子主题
全量复制
部分复制
原理和流程
主从数据
设置redis.conf文件中的requirepass pass 设置密码
获取密码:CONFIG get requirepass
设置密码:CONFIG set requirepass pass
redis默认没有密码,可以通过requirepass设置密码
AUTH password
redis可以连接,但是不能操作需要输入密码
./redis-cli 127.0.0.1 -p 6379 -a pass
连接时输入密码
redis设置密码时
安全
PUBLISH channel message
发布
publish
SUBSCRIBE channel [channel ...]
订阅
subscribe
取消订阅
unsubscribe
活跃频道指的是那些至少有一个订阅者的频道
pubsub
SUBSCRIBE channel.*
psubscribe
发布/订阅
一个key中最大存储512M的数据
特性
get/set
mset name caijian sex man age 23
mget name sex age
多个key操作
mget/mset
getrange name 3 6
获取指定下标范围内的字符串
getrange
setrange name 3 jian
设置指定下表开始替换字符,有多长替换多长
setrange
setex name 600 ciajian
相当于set + expire命令的组合
setex
查询/赋值
incr nums
将 key 中储存的数字值增 1,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作,字符串类型的值不能表示为数字,那么返回一个错误
incr
incrby nums 10
incrby
decr nums
自减 1
decr
decrby nums 10
自减 指定数
decrby
append name caijian
追加字符串
append
字符串长度
strlen
基本命令
get num1 0
获取二进制中offset这个位置的“0,1”状态
getbit
set num1 7 1
设置二进制中offset这个位置的“0,1”状态
setbit
bitcount num1
获取二进制中1的个数
bitcount
BITOP AND destkey key [key ...]
BITOP OR destkey key [key ...]
BITOP XOR destkey key [key ...]
BITOP NOT destkey key
bitop
二进制
redis中用SDS表示字符串
二进制安全的数据结构:C语言字符串以/0结尾,不能兼容其他语言的字符串类型
内存预分配机制,避免频繁的内存分配
SDS:Simple Dynamic String
存储8个字节的长整形
int
raw需要分配两次内存空间
存储大于44个字节的字符串
raw
只分配一次内存空间
embstr是只读的,如果修改value后就变成raw了
如果int数据不再是整数,会从int类型变成raw
存储小于等于44个字节的字符串
embstr
String的三种存储结构
string
ziplist是一个双向链表,但是不存preview和next指针,存的是上一个节点的长度和当前结点的长度
当hash中存储的field小于512个的时候,这时候用ziplist
hash中所有的field和value的字符串长度都小于64byte
ziplist
数组加链表
hash table
购物车
应用场景
存储结构
hash
删除,并获取第一个元素
BLPOP key[key ...]
删除,并获取最后一个元素
BRPOP key[key ...]
弹出一个列表值,将他插入到另一个列表中
BRPOPLPUSH source destination
通过索引获取一个元素
LINDEX key index
在列表中的另一个元素之前或之后插入元素
LINSERT key BEFORE|AFTER pivot value
获取队列长度
LLEN key
从队列左边出队一个元素
LPOP key
从队列的左边入队一个或多个元素
LPUSH key value[value]
当队列存在时,从队左边入队一个元素
LPUSHX key value
获取指定的元素
LRANGE key start stop
从列表中删除元素
LREM key count value
根据下标设置队列元素值
LSET key index value
LTRIM key start stop
从队列右边出队一个元素
RPOP key
删除队列最后一个元素,最加到另一个队列
RPOPLPUSH source destination
从队列右边入队一个元素
RPUSH key value[value ...]
从队列右边入队一个元素,仅队列存在时有效
RPUSHX key value
quick list+zip list
文章列表
消息列表
评论列表
List
添加一个或多个元素到集合中
SADD key member[member]
获取集合中元素数量
SCARD key
获取集合交集
SUBTER key [key]
获取集合交集并存储在一个结果集上
SINTERSTORE destination key [key ...]
获取集合中所有元素
SMEMBERS key
移动集合中的一个元素到另一个集合
SMOVE source destination member
删除集合里的元素
SPOP key [count]
随机获取一个元素
SRANDMEMBER key[count]
集合里删除一个或多个元素
SREM key member [member]
添加多个set元素
SUNION key[key...]
合并set元素,并将结果存入新的set
SUNIONSTORE DESTINATION KEY[KEY ...]
intset
hashtable
spop
抽奖
sinter
sdiff
对账
sadd
srem
sismember
smembers
社交关注、点赞
去重
set
skip list
zincrby
zrevrange
热搜排行
SortedSet
基本数据类型命令
批量设置缓存时,增加随机的缓存过期时间,避免在同一时刻点大批量缓存失效
缓存击穿(只穿透了缓存)
缓存空值,并设置过期时间,增加缓存读延期
布隆过滤器
缓存穿透(缓存和DB都击穿了)
缓存高可用架构,多级缓存,包括JVM级的缓存
限流组件
缓存雪崩
突发性热点缓存重建,导致数据库压力暴增
通过分布式锁(读写锁,确保读读不互斥),确保只有一个线程来重建缓存
使用双重检测机制确保查询尽量走缓存
突发性热点缓存重建
本质问题是从数据库取值到设置redis这个过程不是原子操作,所以要对DB和redis的操作加分布式锁
redis和DB的双写一致性问题
锁粒度:分段锁
读写锁
分布式锁性能优化方案
master上加锁成功,在同步给slaver时,master挂了,导致其他线程可以在slaver上在加相同的锁
Red Lock,加锁时和Zk类似,需要过半加锁成功才算加锁成功
red lock下添加从结点的时候,可能发生主节点崩溃,所以red lock也不能彻底解决这个问题
如果设置多个从结点的话,会影响redis加锁性能
主从切换锁丢失
分布式环境下加分布式锁的问题
redis的分布式锁是基于ap的,只要主节点加锁成功,则返回加锁成功
zk的分布式锁是基于cp的,需要过半提交
和zk分布式锁的区别
https://mp.weixin.qq.com/s/SRsbscvQo9Y2H0IUM0Sx6Q
redisson源码分析
Redis分布式锁
热点数据尽量常驻在缓存中
缓存设置过期时间
缓存命中增加读延期
热点数据冷热分离
底层是一个bitmap二进制数组和几个无偏hash函数(元素的hash值均匀分布)
布隆过滤器说某个值存在时,这个值可能不存在;当它说某个值不存在时,那就肯定不存在
布隆过滤器误差率
布隆过滤器元素个数(布隆过滤器长度)
影响因素
布隆过滤器不能删除数据,如果要删除,就得重新初始化
高性能键值对数据库
共享内存[专门的内存空间]
特点
历史发展
字符串(String)
哈希/散列/字典(Hash)
列表(List)
集合(Set)
有序集合(sorted set)
内存存储与持久化
数据库(database)
缓存(cache)
消息中间件(message broker)
功能丰富
语法简单
稳定
简单稳定
官方文档:http://doc.redisfans.com/
简介
keys n?me
keys n*me
keys n[]me
keys n\\?me
模式匹配
redis中key全部是以String类型来处理
keys
exists name
判断指定的key是否存在,存在返回 1 不存在返回 0
exists
del name
删除key,返回删除的数量
del
type name
查看key类型
type
randomkey
返回一个随机key
expire name 60
设置key过期时间
expire
ttl name
ttl
expireat 140090898092890
以某个时间点为过期时间,-毫秒,expireat 时间戳;
expireat
sort name
sort name desc
数字
sort name alpha
sort name alpha desc
字符串
排序
sort
KEY
强制清空所有数据库中的所有key
flushall
清空当前数据库中的所有 key
flushdb
所有连接到服务器的客户端信息和统计数据
CLIENT LIST
CLIENT KILL 127.0.0.1:43501
关闭地址为 ip:port 的客户端
CLIENT KILL
向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG
PING
打印一个特定的信息 message ,测试时使用
ECHO
请求服务器关闭与当前客户端的连接
QUIT
server
事务开始
multi
事务结束
exec
取消事务,放弃执行事务块内的所有命令
discard
监视key变化,发生变化时会取消事务
watch
取消 WATCH 命令对所有 key 的监视
unwatch
Transaction(事务)
sentinel用于监视master是否正常在线,如果master挂掉了,sentinel会在slave中选举出一个master顶上去
开3个Sentinel或者说开奇数个,Sentinel的原理就是一直监视着master是否在线, 如果挂掉,sentinel的集群会选举中一个领头的sentinel,然后由领头的sentinel 执行slaveof命令,让slave作为master,然后sentinel集群继续监视着新的master, 老的master还是会一直监控着,如果启动了,那么老的master会作为新master的slave。
主观下线:sentinel发现master没有在指定时间返回信息,这种情况被认为主线下线。
客观下线:sentinel询问sentinel的集群,看一下其他的sentinel是否也标记这master是否下线,如果标记sentinel下线的个数达到一个阀值,sentinel会将master标记为客观下线,这个时候能会选取领头的sentinel。由领头的sentinel选取master下面的一个slave去作为新的master。
sentinel判断master下线的两种标准
sentinel monitor mymaster 127.0.0.1 6379 2
你要监视的主服务器的ip地址,以及sentinel标记客观下线的阀值
sentinel down-after-milliseconds mymaster 3000
sentinel认为“主线下线”的一个阀值
sentinel parallel-syncs mymaster 1
故障恢复期间可以同时slave的个数
sentinel failover-timeout mymaster 180000
故障恢复允许的最大时长
默认会有一个实例ID,注释掉每次启动会自动分配sentinel myid
如果redis设置了密码需要配置密码,不支持主从密码不一致:sentinel auth-pass mymaster pass
哨兵 sentinel
redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。
Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位,槽位的信息存储于每个节点中。
Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。HASH_SLOT = CRC16(key) mod 16384
当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。
集群中的每个节点都有 1 个至 N 个replica, 其中一个结点为主节点(master), 而其余的 N-1 个结点为从节点(slave),主节点宕机后其他服务器会选举出其中一个slave为新的主节点,否正整个集群将停止运作,因为没有对应的服务器承接相应的哈希槽
1.slave发现自己的master变为FAIL
2.将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息
3.其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
4.尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
5.slave收到超过半数master的ack后变成新Master
从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟•延迟计算公式:DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms•SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举
Redis集群选举原理
Redis 集群不保证数据的强一致性
集群启动必须保证redis为空,清除appendonly.aof,dump.rdb,和 cluster-config-file配置的文件
环境
daemonize yes
:password => \"root\
vi /usr/local/rvm/gems/ruby-2.4.4/gems/redis-4.0.1/lib/redis/client.rb
如果有密码需要配置密码
./redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
redis全部启动后,启动集群
创建集群
集群cluster
当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期的key
优点:避免主动删除导致redis有卡顿
缺点:如果key不在被访问,会一直占内存,相当于过期失效
被动删除
Redis定期主动淘汰一批已过期的key
针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除
volatile-ttl
对设置了过期时间的键值对中,进行随机删除
volatile-random
使用LRU算法筛选设置了过期时间的键值对删除
volatile-lru
使用LFU算法筛选设置了过期时间的键值对删除
volatile-lfu
针对设置了过期时间的key做处理
从所有键值对中进行随机选择并删除数据
allkeys-random
使用LRU对所有数据进行筛选删除
allkeys-lru
使用LFU对所有数据进行筛选删除
allkeys-lfu
针对所有的key做处理
淘汰很久没有被访问过的数据,以最近一次访问时间作为参考
LRU
淘汰最近一段时间被访问次数最少的数据,以访问次数作为参考
热点数据适合用LFU
LFU
主动删除
当内存超过maxMemory(在redis.conf里配置的)限定时,触发主动删除策略
不会删除任何数据(不做任何处理,直接报错)
noeviction
过期键清除策略
redis连接池中最大连接数,不能超过maxTotal
节点数 * maxTotal < redis最大连接数maxClients
maxTotal
业务需要的最大连接数
如果超过了maxIdle,当超过的连接执行完业务后会慢慢被连接池释放掉
maxIdle不要设置的太小,否则会有new 连接的开销,建议maxIdle=maxTotal
maxIdle:最大空闲连接数
至少要保持的空闲连接数,如果超过了minIdle,那么继续建立连接
minIdle:最小空闲连接数
关键参数
连接池预热
redis连接池
redis
0 条评论
回复 删除
下一页