缓存--Redis

Redis的数据结构和常用命令

Redis是一个开源的用c语言编写,支持网络,基于内存的持久化型Key-Value数据库,并提供了多种语言API。本质是客户端-服务应用软件程序。特点是使用简单、性能强悍、功能应用场景丰富。可以理解为一个增强版的hashmap。
官网:redis.io
在这里插入图片描述
支持地数据结构有7种:
1、String:String数据接受是简单的key-value类型,value其实不仅是String,也可以是数字。
使用场景:微博数,粉丝数(常规计数)
在这里插入图片描述
2、List:List就是链表,相信略有数据结构知识的人都应该能理解其结构。
使用场景:微博的关注列表,粉丝列表
在这里插入图片描述

3、Set就是一个集合,集合的概念就是一堆不重复的组合。利用Redis提供的Set数据结构,可以存储一些集合性的数据。
使用场景:实现共同关注、共同喜好、社交好友
在这里插入图片描述
4、Sorted set:Sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级的参数来为成员排序,并且是插入有序的,即自动排序。
使用场景:排行榜、按照用户投票和时间排序。
在这里插入图片描述
5、Hash:hash是一个String类型的field和value的映射表
使用场景:存储部分变更数据,如用户信息
在这里插入图片描述
6、GEO:GEO 3.2版本开始对GEO(地理位置)的支持
使用场景:LBS应用开发
在这里插入图片描述
7、Stream:Stream 5.0版本开始的新结构 “流”
使用场景:消费者生产者场景(类似MQ)
在这里插入图片描述
在使用中,大多数人是这么用的:
在这里插入图片描述
这样写,没错,但是代码太多,加了redis使用多出了很多代码,可以使用这种简单的方式
在这里插入图片描述
redis的性能,我们可以去官网中看到一个性能结果:
set:每秒12w次,这个值和集器的cpu有很大的关联,cpu执行效率越高,redis性能越好。
在这里插入图片描述

Redis持久化机制

Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上, 当redis重启后,可以从磁盘中恢复数据。
在这里插入图片描述
持久化的方式分为2种:
1、RDB持久化:RDB持久化方式能够在指定的时间间隔对你的数据进行快照存储
客户端直接通过命令BGSAVE或者SAVE来创建一个内存快照
a、BGSAVE调用fork来创建一个子进程,子进程负责将快照写入磁盘,而父进程仍然继续处理命令
b、SAVE执行SAVE命令过程中,不再相应其他命令。
在redis.conf中调整save配置选项,当在规定的时间内,Redis发生了写操作的个数满足条件会触发发生BGSAVE命令
在这里插入图片描述
RDB的有点和缺点
在这里插入图片描述

2、AOF(append only file)持久化:AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据
a、开启AOF持久化
在redis.conf里面修改appendonly yes(默认是关闭–>appendonly no)
b、AOF策略调整
在这里插入图片描述
AOF的优点和缺点:
在这里插入图片描述

Redis内存分配

redis在存储数据的时候会根据类型的不同来做一些内存的限制
在这里插入图片描述
内存压缩配置:
hash-max-zipmap-entries 512:意思就是配置字段最多512个,在存hash类型的内容时,少于512个元素,redis会使用算法压缩,超出512就不会压缩,因为压缩也消耗cpu。
当然有很多这样的配置:
在这里插入图片描述
过期数据的处理策略:
主动处理(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 noevicion
动态调整(通过命令行的方式):config set maxmemory-policy noevocion
在这里插入图片描述
LRU算法:根据数据的历史访问记录来进行淘汰数据。
核心思想:如果数据最近被访问过,那么将来被访问的几率也很高
注意:Redis的LRU算法并非完整的实现,完整的LRU实现是因为这需要太多的内存。
方法:通过对少量keys进行取样(50%),然后回收其中一个最好的key
配置方式:masmemory-samples 5

LFU算法:根据数据的访问频率来淘汰数据
核心思想:如果数据被访问多次,那么将来被访问的频率也高
Redis实现是近似的实现,每次对key进行访问时,用基于概率的对数计算器来记录访问次数,同时这个计算器会随着时间推移而减小。
Morris counter算法依据:https://en.wikipedia.org/wiki/Approximate_counting_algorithm
启用LFU算法后,可以使用热点数据分析功能。(redis-cli-hotkeys)

Redis主从复制

主从复制就是redis的主服务器将数据复制到redis的从服务器,这么用主要是为了解决redis-server单点故障和单点的redis,QPS是有限的。适用场景就是读写分离场景,规避了redis的单机瓶颈;故障切换,master出问题之后还有slave节点可以使用。

搭建主从复制:主Redis Server以普通模式启动,主要是启动从服务器的方式
1、命令行:连接需要实现从节点的redis,执行命令 slavedof [ip] [port]
2、redis.cong配置文件:配置文件中添加slaveof [ip] [port],从服务器是否只读(默认yes) slave-read-only yes
退出主从集群的方式: Slaveof no one

主从复制流程:
在这里插入图片描述
1、从服务器通过psync命令发送服务器已有的同步进度(同步源ID、同步进度offset)
2、master收到请求,同步源为当前master,则根据偏移量增量同步
3、同步源非当前master,则进入全量同步:master生成rdb,传输到slave,加载到slave内存

主从复制核心知识:
1、redis默认使用异步复制,slave和master之间异步地确认处理地数据量
2、一个master可以拥有多个slave
3、slave可以接受其他slave的链接。slave可以有下级的sub slave
4、主从同步过程在master侧是非阻塞的
5、slave初次同步需要删除旧数据,加载新数据,会阻塞到来的连接i请求
在这里插入图片描述
主从复制的应用场景:
1、主从复制可以用来支持读写分离
2、slave服务器设定为只读,可以用在数据安全的场景下
3、可以使用主从复制来避免master持久化造成的开销。master关闭持久化,slave配置为不定期的保存或是启用AOF.(注意:重新启动的mater程序将从一个空数据集开始。如果一个slave试图与它同步,那么这个slave也会被清空)

主从复制的注意事项:
读写分离场景:
1、数据复制延时导致读到过期数据或者读不到数据(网络原因,salve阻塞)
2、从节点故障(多个client如何迁移)
全量复制情况下:
1、第一次建立主从关系或者runnid不匹配会导致全量复制
2、故障转移的时候也会穿全量复制
复制风暴:
1、master故障重启,如果slave节点较多,所有slave都要复制,对服务器的性能,网络的压力都有很大的影响
2、如果一个极其部署了多个master
写能力有限:
1、主从复制还是只是一台master,提供的写服务能力有限
master故障情况下:
1、如果是master无持久化,slave开启持久化来保留数据的场景,建议不要配置slave自动重启
2、启动redis自动部署,master启动后,无备份数据,可能导致集群数据丢失的情况
带有效期的key:
1、slave不会让key过期,耳饰等待mster让key过期
2、在Lua脚本执行期间,不执行任何key过期操作

Redis哨兵可用机制

在这里插入图片描述
哨兵(Sentinel)机制核心作用:
客户端不在关心集群,而是交给哨兵管理,哨兵负责监控集群的主从切换以及故障转移。客户端想要操作集群只能通过哨兵来询问。哨兵也可以是集群,单台哨兵服务检测到redis主节点故障也有可能是哨兵自身出的原因,所以必须有一定数量的哨兵共同认为主节点发生了故障时,才能确定主节点发生了故障。

哨兵的配置文件:
在这里插入图片描述

服务发现和健康检查流程:
在这里插入图片描述
故障切换流程:
在这里插入图片描述
哨兵的核心问题:
1、什么是主观下线(sdown)?
主观下线:单个哨兵自身认为redis实例已经不能提供服务
检测机制:哨兵向redis发送ping请求,+PONG、-LOADING、-MASTERDOWN这三种情况为正常,其他回复都是无效的。
对应配置文件的配置项:sentinel down-after-milliseconds mymaster 1000
2、什么是客观下线(odown)
客观下线:一定数量值的哨兵认为master已经下线
监测机制:当哨兵主观任务master下线后,则会通过SENTINEL is-master-down-by-addr命令,询问其他哨兵是否认为master已经下线,如果达成共识(达到quorum这个数),就会认为master节点客观下线,开始故障转移流程。
对应配置文件的配置项:sentinel monitor mymaster 60.205.209.106 6380 2
3、哨兵之间如何通信?
在这里插入图片描述
4、哨兵之间领导选举机制是什么?
基于Raft算法实现的选举机制,流程简述如下:
a.拉票阶段:每个哨兵节点希望自己成为领导者
b.sentinel节点收到拉票命令后,如果没有收到或同意过其他节点的sentinel节点的请求,就同意该sentinel节点的请求(每一个sentinel只持有一个同意票数)
c.如果sentinel节点发现自己的票数已经超过一半的数量,那么他将成为领导者,去执行故障转移。
d.投票结束后,如果超过failover-timeout的时间内,没进行实际的故障转移操作,则重新拉票选举。
注意:以了解raft协议为主。https://raft.github.io/、http://thesecretlivesofdata.com/
每个哨兵都会去向其他的哨兵去拉票,所以可能造成每一个哨兵的票数一样,无法选举新的主节点,所以raft是以随意时间来确定,也就是每一个哨兵的请求拉票的时间不一样,先去拉票的哨兵就有比较大的概率选举成功。
5、slave选举方案是什么?
a.判断节点状态,非S_DOWN,O_DOWN,DISCONNECTED。
b.优先级,redis.conf中的一个配置项:slave-priority值越小,优先级越高。
c.数据同步情况,Replication offset processed
d.最小的 run id,run id比较方案,字典顺序,ASCII码
6、最终主从切换的过程
a.针对即将成为master的slave节点,将其撤出主从节点集群,自动自行:slaveof no one
b.针对其他slave节点,使他们成为新master的从属,自动执行:slave new_master_host new_msater_port

Redis集群分片存储

为什么要是用分片?
例如:公司用户量3千万,用户基本信息缓存到redis中,需要内存10G,如何设计Redis的缓存架构?
1、3千万的用户,各种业务场景对用户信息的访问量很大,单台redis示例的读写瓶颈
2、单redis实例管理10G内存,必然影响处理效率
3、redis的内存需求可能超过机器的最大内存,一台机器不够用
因此,引出了分片存储的技术。
官方给出的集群方案:
redis cluster是redis的分布式集群解决方案,在3.0版本推出后有效地解决了redis分布式方面的需求,实现了数据在多个redis节点之间自动分片、故障自动转移、扩容机制等功能。
在这里插入图片描述
集群关心的问题:
1、增加了slot槽的计算,是不是比单机性能差?
共16384个槽,slots槽计算方式公开的,HASH_SLOT=CRC16(key) mod 16384。为了避免每次都需要服务器计算重定向,优秀的jaba客户端都实现类了本地计算,并且缓存服务器slots分配,有变动时再更新本地内容,从而避免了多次重定向带来的性能损耗。
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、slot手动迁移怎么做?
a、在迁移目的节点执行cluster setslot IMPORTING 命令,知名需要迁移的slot和迁移源节点
b、在迁移源节点执行cluster setslot MIGRATING 命令,指明需要迁移的slot和迁移目的节点
c、在迁移源节点执行cluster getkeysinslot获取该slot的key列表
d、在迁移源节点执行对每个key执行migrate命令,该命令会同步把该key迁移到目的节点
e、在迁移源节点反复执行cluster getkeysinslot命令,直到该slot的列表为空
f、在迁移源节点和目的节点执行cluster setslot NODE ,完成迁移操作。
7、节点之间会交换信息,传递的消息包括槽的信息,带来宽带消耗。
注意:避免使用大的一个集群,可以分多个集群。
8、Pub\Sub发布订阅机制
注意:对集群内任意的一个节点执行public发布消息,这个消息会在集群中进行传播,其他节点接收到发布的消息。
9、读写分离
a、redis-cluster默认所有的从节点上读写,都会重定向到key对接槽的主节点上。
b、可以通过readonly设置当前连接可读,通过readwrite取消当前连接的可读状态。
注意:主从节点依然存在数据不一致的问题。

Redis监控

1、Monitor命令
monitor是一个调试命令,返回服务器处理的每个命令。对于发现程序的错误非常有用。出于安全考虑,像一些修改密码的命令是不会记录的。
警告:谨慎使用,运行monitor命令能降低50%的吞吐量,运行多个monitor命令降低的吞吐量更多。
2、info命令
info命令以一种易于理解和阅读的格式,返回关于redis服务器的各种信息和统计数值。
在这里插入图片描述
可以用过section返回部分信息,如果没有使用任何参数时,默认是default。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Go微服务中使用Redis缓存是一种常见的做法。通过引入动态缓存配置文件和初始化dynamic_cache.go中的公有值,可以实现对Redis缓存的配置和初始化。在配置文件中使用include命令引入动态缓存配置文件(dynamicache.conf),可以更方便地管理和修改缓存配置。在sysinit/sysinit.go文件中,有一个函数initDynamicCache用于初始化dynamic_cache.go中的公有值,并初始化Redis配置。可以通过设置MaxOpen、MaxIdle和ExpireSec等参数来配置Redis缓存的最大连接数、最大空闲连接数和缓存过期时间。通过调用dynamicache.InitCache()方法来初始化Redis缓存。这样就可以在Go微服务中使用go-redis缓存了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [go-redis-cache:使用Redis缓存进行微服务](https://download.csdn.net/download/weixin_42131628/16618478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Go项目优化——动态缓存Redis的使用](https://blog.csdn.net/weixin_52000204/article/details/127338089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值