Redis相关知识

Redis简介

Redis是一个开源的使用C语言编写、支持网络、可基于内存亦可持久化的日执行、Key-Value数据库,并提供多种语言的API。
本质是客户端-服务端应用软件程序。
特点是使用简单、性能强悍、功能应用场景丰富。

数据格式

String
String数据格式是简单的Key-Value类型,value其实不仅是String,也可以是数字。
使用场景:微博数,粉丝数(常规计数)
List - stack
List就是链表,相信略有数据结构知识的人都应该能够理解其结构
使用场景:微博的关注列表,粉丝列表
Set
set就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的Set数据结构,可以存储一些结合性的数据。
使用场景:实现如共同关注、共同喜好、二度好友
Sorted set
Sorted set是使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序
使用场景:排行榜、按照用户投票和时间排序
Hash
Hash是一个string类型的field和value的映射表
使用场景:存储部分变更数据,如用户信息
GEO
GEO 3.2版本开始对GEO(地理位置)的支持
使用场景:LBS应用开发
Stream
Stream5.0版本开发的新结构流
使用场景:消费生产者场景(类似MQ)

可以使用list实现mq的功能
批量处理pepline方式
清空数据flushdb
bub/sub 发布订阅机制topic 不会持久化

常用命令

常规操作
DEL key 该命令用于在key存在的时删除key
DUMP key 序列化给定key,并返回被序列化的值
EXISTS key 检查给定key是偶存在
EXISTS key seconds 为给定key设置过期时间,以秒计
TTL key 以秒为单位,返回给定key的剩余生存时间(TTL,time to live)
TYPE key 返回key所储存的值的类型
keys 查询所有的value
String类型操作
set key value 设置制定key的值
get key 获取正定key的值
incr 将key中存储的数字值增一
decr 将key中存储的数字值减一
mget 获取所有(一个或多个)给定key的值
List类型操作
lpush 将一个或多个值插入到列表头部
rpush 在列表汇总添加一个或多个值
lpop 移出并获取列表的第一个元素
rpop 移除列表的最后一个元素,返回值为移除的元素
lrange 获取所有(一个或多个)给定key的值
Set类型操作
sadd 向集合中添加一个或多个成员
spop 移除并返回结合中的一个随机元素
smembers 返回集合中的所有成员
sunion 返回所有给定集合的并集
Sorted set 类型操作
zadd 向有序集合体检一个或多个成员,或者更新已存在成员的分数
zrange 通过索引区间返回有序集合中指定区间内的成员
zrem 移除有序集合中的一个或多个成员
zcard 获取有序集合的成员数
Hash类型操作
hget 获取存储在哈希表中指定字段的值
hset 将哈希表key中的字段field的值设为calue
hgetall 获取在哈希表中指定key的所有字段的值
GEO类型操作
geoadd 增加地址位置的坐标,可以批量添加地理位置
geodist 获取两个地址位置的距离
geohash 获取某个地址位置的geohash值
geopos 获取指定位置的坐标,可以批量获取多个地理位置的坐标
georadius 根据给定地理位置坐标获取指定范围内的地理位置集合
georadiusbymember 根据给定成员的位置获取指定范围内的位置信息集合
Stream类型操作
xadd 往指定的流中添加消息
xlen stream流中的消息数量
xdel 删除流中的消息
xrange 返回流中满足给定id范围的消息
xread 从一个或多个流中多去消息
xinfo 检索关于流和关联的消费者组的不同的消息

工具类

jedis
spring redisTemplate
springboot 使用redis容器的方式
redisson和lettuce
monitor可以打印redis收到的所有命令,可以用于调试
可以接受内部的指令,key的动态通知,可以监听某一个key的变化,或者监听一类事件的数据变化
修改配置文件 eventNotifi
Stream数据类型 redisson和lettuce进行了支持 与发布订阅不同的是,有持久化
使用分组消费Stream不会重复处理数据 xreadgroup分组消费的时候分组内的消费者处理完数据要返回xack,否人为消息没有被消费,会被挂起进入pengding队列,消息要重新分派,需要手动重新分派
在这里插入图片描述

Redis持久化介绍

Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据
在这里插入图片描述
持久化方式
RDB持久化
RDB持久化方式能够在制定的时间间隔对你的数据进行快照存储 --二进制文件的形式存储
AOF(append only file)持久化
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来回复原始的数据–操作日志
RDB方式
客户端直接通过命令bgsave或者save来创建一个内存快照
bgsave调用fork来创建一个子进程,子进程负责将快照写入磁盘,而父进程任然继续处理命令。
save执行save命令过程中,不在响应其他命令
在redis.conf中调整save配置选项,当在规定的时间内,Redis发生了写操作的个数满足条件会触发发生bgsave
#900秒之内至少一次写操作
save 900 1
#300秒之内至少10次写操作
save 300 10 --每3秒去检查一次
RDB优缺点

优点 缺点
对性能影响小 同步时会丢失数据
RDB文件进行数据恢复比AOF要快很多 如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时会消耗相对较长的时间,影响Redis对外停工服务的能力
正常关闭会保存一次快照,异常关闭会有数据丢失

AOF持久化方式
开启AOF持久化
appendonly yes
AOF策略调整
#每次有数据修改发生时会写入AOF文件
appendfsync always
#每秒钟同步一次,该策略AOF的缺省策略
appendfsync everysec
#从不同步,高效但是数据不会被持久化
appendfsync no
优点 缺点
最安全 文件体积大
容灾 性能消耗比RDB高
易读、可修改 数据恢复速度比RDB慢

Redis内存管理

内存分配
不同数据类型的大小限制
Strings类型:一个String类型的value最大可以存储512m。
Lists类型:list的元素个数最多为2^32-1个,也就是4294967295个,每个里面存的都是String类型
Sets类型:元素个数最多为2^32-1个,也就是4294967295个,每个里面存的都是String类型
Hashs类型:键值对个数对多为2^32-1个,也就是4294967295个,每个里面存的都是String类型
#最大内存控制
maxmemory 最大内存阈值
maxmemory-policy 到达阈值的执行策略
内存压缩
Hash类型
#配置字段最多512个
hash-max-zipmap-entries 512
#配置value最大为64字节
hash-max-zipmap-value 64
List类型
#配置元素个数最多512个
list-max-ziplist-entries 512
#配置value最大为64字节
list-max-ziplist-entries 64
Set类型
#配置元素个数最多512个
set-max-intset-entries 512
Sort set类型
#配置元素个数最多128个
zset-max-ziplist-entries 512
#配置value最大为64字节
zset-max-ziplist-entries 64
大小超出压缩范围,溢出后Redis将自动将其转换为正常大小
过期数据的处理
主动处理(redis主动触发检查key是否过期)每秒执行10次。过程如下:
1、从具有相关过期的密钥集中测试20个随机密钥
2、删除找到的所有密钥已过期
3、如果超过25%的密钥已过期,从步骤1重新开始

被动处理
1、每次访问key的时候,发现超时后被动过期,清除掉
数据恢复阶段过期数据的处理策略
RDB方式
过期的key不会被持久化到文件中。
载入时过期的key,会通过redis的主动额被动方式清理掉
AOF方式
当redis使用AOF方式持久化时,每次遇到过期的key redis会追加一条del命令道AOF文件,
也就是说只要我们顺序载入执行AOF命令文件就会删除过期的键。
注:过期数据的计算和计算机本身的时间是有直接联系的
Redis内存回收策略
配置文件中设置maxmemory-policy noeviation
动态调整指令 config set maxmemory-policy noeviation
回收策略 说明
noeviction 客户端尝试执行会让更多内存被使用的命令直接报错
allkeys-lru 在所有key里执行LRU算法
volatile-lru 在所有已经过期的key里执行LRU算法
volatile-lfu 使用过期集在密钥中使用近似LFU进行逐出
allkeys-lfu 在所有近似LFU逐出任意键
allkeys-random 在所有key里面随机回收
volatile-random 在已经过期的key里面随机回收
volatile-ttl 回收已经过期的key,并且优先回收存活时间(ttl)较短的键
LRU
LRU(last recently used)最近最少使用:根据数据的历史访问记录来进行淘汰数据
核心思想:如果数据最近被访问过,那么将来被访问的几率也更高
注意:Redis的LRU算法并非完整的实现,完整的LRU实现是因为这需要太多的内存。
方法:通过对少量keys进行取样(50%),然后回收其中一个最好的key
配置方式 maxmemory-samples 5
LFU
LFU(least frequently used)根据数据的历史访问频率来淘汰数据
核心思想:如果数据过去被访问多次,那么将来被访问的频率也更高
Redis山西爱你的是近似的实现,每次对key进行访问时,用基于改了的对数计数器来记录访问次数,同时这个计数器会算着时间推移而减小。
Morris counter算法
启用LFU算法后,可以使用热点数据分析功能(redis-cli --hotkeys)

主从复制介绍

在这里插入图片描述
为什么使用主从复制
解决redis-server单点故障
单节点QPS有限

主从复制应用场景分析
读写分离场景,规避redis单机瓶颈
故障切换,master出问题后还有slave节点可以使用

搭建主从复制
主Redis Server以不同模式启动,主要是启动从服务器的方法
1、第一种方式:命令行
#连接需要实现从节点的redis,执行下面的命令
slaveof [ip] [port] >>>>>>replicaof
2、第二种方式:redis.conf配置文件
#配置文件中增加
slaveof [ip] [port]
#从服务器是否只读(默认yes)
slave-read-only yes
退出主从集群的方式
Slaveof no one
redis里面有一种ip绑定的机制,需要修改配置文件,使用bind [ip] 配置
检查主从复制
可以使用info replication 命令,查看主从配置信息
主从复制流程

1、从服务器通过psync命令发送服务器已有的同步进度(同步源ID、同步进度offset)
2、master收到请求,同步源为master,则根据偏移量增量同步-----把命令实时转发到slave
3、同步源非当前master,则进入全量同步:master生成rdb,创疏导slave,加载到slave内存----同步rdb文件
partial synchronzation 局部复制
主从复制核心知识
redis默认使用异步复制,slave和master之间异步地确认处理的数据
一个master可以拥有多个slave
slave可以接受其他slave的连接。slave可以有下级sub slave
主从同步过程在master侧是非阻塞的
slave初次同步需要删除旧数据,加载新数据,会祖册到来的连接请求
主从复制应用场景
主从复制可以用来支持读写分离
slave服务器设定为只读,可以用在数据安全的场景下。
可以使用主从复制来避免master持久化造成的开销。master关闭持久化,slave配置为不定期保存或者启用AOF。(注意:重新启动的master程序将从一个空数据集开始,如果一个slave试图与他同步,那么这个slave也会被清空。)
主从复制的注意事项
读写分离场景:
数据复制延时导致读到过期数据或者读不到数据(网络原因、slave阻塞)
从节点故障(多个client如何迁移)

全量复制情况下:
第一次建立主从关系或者runid不匹配会导致全量复制
故障转移的时候也会出现全量复制

复制风暴:
master故障重启,如果slave节点较多,所有slave都要复制,对服务器的性能,网络的压力都有很大影响
如果一个机器部署了多个master

写能力有限:
主从复制还是只有一台master,提供的写服务能力有限

master故障情况下:
如果是master无法持久化,slave开启持久化来保留数据的场景,建议不要配置redis自动重启
启动master自动重启,master启动后,无备份数据,可能导致集群数据丢失的情况

带有效期的key:
slave不会让key过期,而是等待master让key过期
在lua脚本执行期间,不执行任何key过期操作

主服务器使用ping命令检测从服务器是否可用
java代码如何知道redis的主从信息—info replication 命令

哨兵(sentinel)机制核心作用

在这里插入图片描述
客户端向哨兵询问主服务器地址
哨兵通过ping查看主服务器是否正常
不正常则向其他哨兵发送通知

核心运作流程
服务发现和健康检查流程
v
搭建redis主从集群
v
启动哨兵(客户端通过哨兵发现redis实例信息)
v
哨兵通过连接master发现主从集群内的所有实例信息
v
哨兵监控redis实例的健康情况

故障切换流程

哨兵一但发现master不能正常提供服务,则通知其他哨兵
v
当一定数量的哨兵都认为master挂了
v
选举一个哨兵作为故障转移的执行者
v
执行者在slave中选取一个作为新的master
v
将其他slave重新设置为新的master的从属

7大核心概念
1、哨兵如何知道Redis主从信息(自动发现机制)
2、什么是master主观下线
3、什么是客观下线
4、哨兵之间如何通信(哨兵之间的自动发现)
5、那个哨兵负责故障转移(哨兵领导选举机制)
6、slave选举机制
7、最终主从切换过程

哨兵启动配置
启动命令:redis-server sentinel --sentinel
配置文件启动时指定,运行过程中会自动变更,记录哨兵的监测结果

哨兵如何知道redis主从信息
通过info replication 命令检测
哨兵配置文件中,保存着主从集群中master的信息,可以通过info命令,进行主从信息自动发现

什么是master主观下线(sdown)
通过ping命令监控master节点
主观下线:单个哨兵自身认为redis实例已经不能提供服务
监测机制:哨兵向redis发送ping请求,+PONG、-LOADING、-MASTERDOWN者三种情况视为正常,其他回复均视为无效
对应配置文件的配置项:sentinel down-after-milliseconds mymaster 1000

什么是客观下线(odown)
客观下线:一定数量的哨兵认为master已经下线
监测机制:当哨兵主观认为master下线后,则会通过 SENTINEL is-master-down-by-addr命令 询问其他哨兵是否认为master已经下线,如果达成共识(达到quorum个数),就会认为master节点客观下线,开始故障转移流程
对应配置文件的配置项:sentinel monitor mymaster ip port 2

哨兵之间如何通信(哨兵之间的自动发现)
在这里插入图片描述
1、哨兵之间的自动发现,redis中使用pub/sub发布订阅机制通过__sentinel__:hello主题,哨兵向主题中发布自己的信息并订阅其他哨兵的信息

2、哨兵之间通过命令进行通信 直接发送命令
3、哨兵之间通过发布订阅进行通信 相互订阅指定主题pub/sub

那个哨兵负责故障转移(哨兵领导选举机制)
基于Raft算法实现的选举机制,流程描述如下:
1、拉片阶段:每个哨兵节点都希望自己成为领导;
2、sentinel节点收到拉票命令后,如果没有收到或同意过其他sentinel节点的请求,就同意该sentinel节点的请求(每个sentinel只持有一个同意票数);
3、如果sentinel节点发现自己的票数已经超过一般的数值,那么它将成为领导者,去指定故障转移;
4、投票结束后,如果超过failover-timeout的时间内,没进行实际的故障转移操作,则重新拉票选举
注:以了解raft协议为主。https://raft.github.io/、http://thesecretlivesofdata.com/
拉票前先随机睡眠,在发起拉票命令,拉票命令是群发的

slave选举机制
从服务器实例中,按右侧顺序依次筛选
slave节点状态,非S_DOWN,O_DOWN,DISCONNECTED
判断规则:(down-after-milliseconds*10)+milliseconds_since_master_is_in_SDOWN_state
SENTINEL slave mymaster
优先级
redis.conf中的一个配置项:slave-priority值越小,优先级越高
数据同步情况
Replication offfset processed
最小的runid
run id 比较方案:字典顺序,ASCII码

最终主从切换过程
针对即将成为master的slave节点,将其撤除主从集群
自动执行:slaveof no one

针对其他slave节点,使他们成为新master的从属
自动执行:slaveof new_master_host new_master_port

哨兵服务部署方案
两个哨兵,不建议
一主两从,三哨兵
一主两从,网络分区下
可能出现数据不一致或丢失
Redis集群非强一致(最终一直)
为什么要分片存储
示例:公司用户量3千万,用户基本信息缓存到redis中,需要内存10g,如何设计redis的缓存架构?
1、3千万用户,各种业务场景对用户信息的访问量很大。(单台redis实例的读写瓶颈凸显)
2、单redis实例管理10g内存,必然影响处理效率
3、redis的内存需求可能超过机器的最大内存。(一台机器不够用)
故此,引出分片存储的技术。

Redis集群方案

官方集群方案
redis cluster是redis的分布式集群解决方案,在3.0版本退出后有效地解决了redis分布式方面的需求,实现了数据在多redis节点之间自动分片、故障自动转移、扩容机制等功能
在这里插入图片描述
集群搭建

集群关系的问题
1、增加了slot槽的计算,是不是比单机性能差?
共16384个槽,slot槽计算方式公开的,HASH_SLOT=CRE16(key) mod 16384
为了避免美的都需要服务器计算重定向,优秀的java客户端都实现了本地计算,并且缓存服务器slot分配,有变动时再更新本地内容,从而避免了多次重定向带来的性能损耗
2、redis集群大小,到底可以装多少数据?
理论是可以做到16384个槽,每个槽对应一个实例,但是redis官方建议是最大1000个实例,存储足够大了
3、集群节点间是怎么通信的?
每个redis集群节点都有一个额外的TCP端口,每个节点使用TCP连接与每个其他节点连接。检测和故障转移这些步骤基本和哨兵模式类似(毕竟是同一个软件,同一个作者)
4、ask和moved重定向的区别
重定向包括两种情况
若确定slot不属于当前节点,redis会返回moved
若当前redis节点整处理slot迁移,则代表此处请求对应的key暂时不在此节点,返回ask,高速客户端本次请求重定向。
5、数据倾斜和访问倾斜的问题
倾斜导致集群中部分节点数据多,压力大。解决方案分为前期和后期
前期是业务层面提前预测,哪些key是热点,在设计的过程中规避。
后期是slot迁移,尽量将压力分摊(slot调整有自动rebalance、reshard和手动)
6、手动迁移怎么做
7、节点之间会交换信息,穿点的消息包括槽信息,带来带宽消耗
注意:避免使用大的集群,可以分多个集群
8、pub/sub发布订阅机制
注意:堆集群内任意的一个节点执行publish发布消息,这个消息会在急群众进行传播,其他节点收到的发布的信息。
9、读写分离
redis-cluster默认所有从节点上的读写,都会重定向到key对接槽的主节点上。
可以通过readonly设置当前连接可读,通过readwrite取消当前连接的可读状态。
注意:主从节点依然存在数据不一致的问题
非官方集群方案
Codis --豌豆荚团队开源产品
twemproxy --推特开源产品
都是redis的代理,与官方集群思路都是一样的,实现了slot分配算法–不活跃,较久远,不推荐使用

Redis监控

monitor命令
monitor是一个调试命令,返回服务器处理的每一个命令。对于发现程序的错误非常有用。出于安全考虑,某些特殊管理命令config不会记录到monitor输出
redis-cli monitor
运行一个monitor命令能够降低50%的吞吐量,运行多个monitor命令降低的吞吐量更多
info命令
info命令以一种易于理解和阅读的格式,返回关于redis服务器的各种信息和统计数值
info命令 返回信息
server redis服务器的一般信息
clients 客户端的连接部分
memory 内存消耗相关信息
persistence 持久化先关信息
stats 一般统计
replication 主从复制信息
cpu 统计CPU的消耗
commandstats redis命令统计
cluster redis集群信息
keyspace 数据库的相关统计
可以通过section返回部分信息,如果没有使用任何参数时,默认为default。
图形化见识工具-redislive

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值