Redis教程

redis-总结目录

本文主要是介绍redis-总结目录,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Redis介绍
1、五种数据类型

字符串(String)、哈希(Map)、列表(List)、集合(Sets)和有序集合(Sorted sets)

2、Redis主从复制

3、Redis持久化

RDB Snapshotting方式持久化(默认方式)

客户端也可以使用save或者bgsave命令通知redis做一次快照持久化

AOF方式持久化

appendonly yes //启用日志追加持久化方式

appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全持久化,不推荐使用。

appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐使用。

appendfsync no //完全依赖操作系统,性能最好,持久化没保证。

4、Redis虚拟内存

vm-enabled yes 开启虚拟内存功能

vm-swap-file /tmp/redis.swap 交换出来value保存的文件路径/tmp/redis.swapvm-max-memory268435456 redis使用的最大内存上限(256MB),超过上限后 redis开始交换value到磁盘swap文件中。建议设置为系统空闲内存的60 %-80%

vm-page-size 32 每个redis页的大小32个字节

vm-pages 134217728 最多在文件中使用多少个页,交换文件的大小 =(vm-page-size* vm-pages)4 GB

vm-max-threads 8 用于执行value对象换入换出的工作线程数量。0 表示不使用工作线程

5、Redis集群

1. 突破了单一计算机内存限制,可以利用到多个计算机的内存和

2. 通过配置多个计算机来拓展计算能力,解决网络、网卡瓶颈

6、配置文件

指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合

Save分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。

Redis默认配置文件中提供了三个条件:

save 900 1

save 300 10

save 60 10000

7、Redis的内存回收

1.Redis过期策略:删除过期时间的key值

1.定时过期

每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

2.惰性过期

只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

3.定期过期

每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

2.Redis淘汰策略:内存使用到达maxmemory上限时触发内存淘汰数据

Redis默认情况下就是使用LRU策略算法。

LRU算法(least RecentlyUsed),最近最少使用算法,也就是说默认删除最近最少使用的键。

缓存清理配置

maxmemory用来设置redis存放数据的最大的内存大小,一旦超出这个内存大小之后,就会立即使用LRU算法清理掉部分数据。

Redis数据淘汰策略

1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。

3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。

4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。

5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。

6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

8、redis哨兵、复制、集群设计原理

哨兵(sentinal)

哨兵是Redis集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题。

1.Redis哨兵主要功能

(1)集群监控:负责监控Redis master和slave进程是否正常工作

(2)消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员

(3)故障转移:如果master node挂掉了,会自动转移到slave node上

(4)配置中心:如果故障转移发生了,通知client客户端新的master地址

3.原理:基本上哪个哨兵节点最先判断出这个主节点客观下线,就会在各个哨兵节点中发起投票机制Raft算法(选举算法),最终被投为领导者的哨兵节点完成主从自动化切换的过程。

Redis 复制(Replication)

Redis为了解决单点数据库问题,会把数据复制多个副本部署到其他节点上,通过复制,实现Redis的高可用性,实现对数据的冗余备份,保证数据和服务的高度可靠性。

①从数据库向主数据库发送sync(数据同步)命令。

②主数据库接收同步命令后,会保存快照,创建一个RDB文件。

③当主数据库执行完保持快照后,会向从数据库发送RDB文件,而从数据库会接收并载入该文件。

④主数据库将缓冲区的所有写命令发给从服务器执行。

⑤以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发送给从数据库。

Redis 主从复制、哨兵和集群这三个有什么区别

主从模式:备份数据、负载均衡,一个Master可以有多个Slaves。

sentinel发现master挂了后,就会从slave中重新选举一个master。

cluster是为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器。

sentinel着眼于高可用,Cluster提高并发量。

1.主从模式:读写分离,备份,一个Master可以有多个Slaves。

2.哨兵sentinel:监控,自动转移,哨兵发现主服务器挂了后,就会从slave中重新选举一个主服务器。

3.集群:为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。

9、Redis的高并发和快速原因

1.redis是基于内存的,内存的读写速度非常快;

2.redis是单线程的,省去了很多上下文切换线程的时间;

3.redis使用多路复用技术,可以处理并发的连接。非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间。

10、为什么Redis是单线程的

1.官方答案

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

2.性能指标

关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求。

3.详细原因

1)不需要各种锁的性能消耗

Redis的数据结构并不全是简单的Key-Value,还有list,hash等复杂的结构,这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在hash当中添加或者删除

一个对象。这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加。

总之,在单线程的情况下,就不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

2)单线程多进程集群方案

单线程的威力实际上非常强大,每核心效率也非常高,多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的。

所以单线程、多进程的集群不失为一个时髦的解决方案。

3)CPU消耗

采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。

但是如果CPU成为Redis瓶颈,或者不想让服务器其他CUP核闲置,那怎么办?

可以考虑多起几个Redis进程,Redis是key-value数据库,不是关系数据库,数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程上就可以了。

Redis单线程的优劣势

单进程单线程优势

  1. 代码更清晰,处理逻辑更简单
  2. 不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
  3. 不存在多进程或者多线程导致的切换而消耗CPU

单进程单线程弊端

  1. 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善;

11、IO多路复用技术

redis 采用网络IO多路复用技术来保证在多连接的时候, 系统的高吞吐量。

多路-指的是多个socket连接,复用-指的是复用一个线程。多路复用主要有三种技术:select,poll,epoll。epoll是最新的也是目前最好的多路复用技术。

12、Redis高并发快总结

1. Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。

2. 再说一下IO,Redis使用的是非阻塞IO,IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。

3. Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。

4. 另外,数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。

5. 还有一点,Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

13、缓存雪崩

数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

1.缓存的高可用性

缓存层设计成高可用,防止缓存大面积故障。即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务,例如 Redis Sentinel 和 Redis Cluster 都实现了高可用。

2.缓存降级

可以利用ehcache等本地缓存(暂时支持),但主要还是对源服务访问进行限流、资源隔离(熔断)、降级等。

当访问量剧增、服务出现问题仍然需要保证服务还是可用的。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级,这里会涉及到运维的配合。

降级的最终目的是保证核心服务可用,即使是有损的。

3.Redis备份和快速预热

1)Redis数据备份和恢复

2)快速缓存预热

4.提前演练

最后,建议还是在项目上线前,演练缓存层宕掉后,应用以及后端的负载情况以及可能出现的问题,对高可用提前预演,提前发现问题。

解决方案:
(一)给缓存的失效时间,加上一个随机值,避免集体失效。
(二)使用互斥锁,但是该方案吞吐量明显下降了。
(三)双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点

I 从缓存A读数据库,有则直接返回

II A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。

III 更新线程同时更新缓存A和缓存B。

14、缓存穿透

缓存穿透是指查询一个一不存在的数据。例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决思路:

如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。

可以给key设置一些格式规则,然后查询之前先过滤掉不符合规则的Key。

解决方案:
(一)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试
(二)采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
(三)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。

15、缓存并发

这里的并发指的是多个redis的client同时set key引起的并发问题。其实redis自身就是单线程操作,多个client并发操作,按照先到先执行的原则,先到的先执行,其余的阻塞。当然,另外的解决方案是把redis.set操作放在队列中使其串行化,必须的一个一个执行。

16、缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。

这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

解决思路:

1、直接写个缓存刷新页面,上线时手工操作下;

2、数据量不大,可以在项目启动的时候自动进行加载;

目的就是在系统上线前,将数据加载到缓存中。

以上就是缓存雪崩、预热、降级等的介绍。

 17、Redis缓存的设计、性能、应用与数据集群同步
  • 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
  • 支持丰富数据类型,支持string,list,set,sorted set,hash
  • 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
  • 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

18、Redis持久化的方式

1.RDB

简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;

2.AOF

换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,+持久化–就像memcache一样。

19、Redis常见性能问题和解决方案

  1. Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
  2. 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
  3. 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
  4. 尽量避免在压力很大的主库上增加从库
  5. 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…。这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

20、Redis的适用场景

1.会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

2.队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

3.全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

4.排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

21、Redis的数据同步方式

无论是主备还是主从都牵扯到数据同步的问题,这也分2种情况:

  • 同步方式:当主机收到客户端写操作后,以同步方式把数据同步到从机上,当从机也成功写入后,主机才返回给客户端成功,也称数据强一致性。 很显然这种方式性能会降低不少,当从机很多时,可以不用每台都同步,主机同步某一台从机后,从机再把数据分发同步到其他从机上,这样提高主机性能分担同步压力。 在redis中是支持这杨配置的,一台master,一台slave,同时这台salve又作为其他slave的master。
  • 异步方式:主机接收到写操作后,直接返回成功,然后在后台用异步方式把数据同步到从机上。 这种同步性能比较好,但无法保证数据的完整性,比如在异步同步过程中主机突然宕机了,也称这种方式为数据弱一致性。

Redis主从同步采用的是异步方式,因此会有少量丢数据的危险。还有种弱一致性的特例叫最终一致性,这块详细内容可参见CAP原理及一致性模型。

 22、分布式与集群

分布式

缓存数据量不断增加时,单机内存不够使用,需要把数据切分不同部分,分布到多台服务器上。 可在客户端对数据进行分片,数据分片算法详见一致性Hash详解、虚拟桶分片。

集群:至少部署两台Redis服务器构成一个小的集群,主要有2个目的:

  • 高可用性:在主机挂掉后,自动故障转移,使前端服务对用户无影响。
  • 读写分离:将主机读压力分流到从机上。

可在客户端组件上实现负载均衡,根据不同服务器的运行情况,分担不同比例的读请求压力。

23、redis和数据库双写一致性问题

分析:一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。
回答:首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。

监听数据binlog更新缓存,保障不丢数据

24、redis中支持事务

支持,使用multi开启事务,使用exec提交事务。

redis发布订阅【了解即可】
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

25、MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

26、Memcache与Redis的区别都有哪些?

1)、存储方式

Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。

Redis有部份存在硬盘上,这样能保证数据的持久性。

2)、数据支持类型

Memcache对数据类型支持相对简单。

Redis有复杂的数据类型。

3)、使用底层模型不同

它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。

Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

4),value大小

redis最大可以达到1GB,而memcache只有1MB

27、Redis 常见的性能问题都有哪些?如何解决?

1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。

2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内

28、

 

 

 

 

 

这篇关于redis-总结目录的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!