首页 > 其他 > 详细

【Redis】四、Redis设计原理及相关问题

时间:2019-06-04 18:46:12      阅读:134      评论:0      收藏:0      [点我收藏+]

(六)Redis设计原理及相关问题

??通过前面关于Redis五种数据类型、相关高级特性以及一些简单示例的使用,对Redis的使用和主要的用途应该有所掌握,但是还有一些原理性的问题我们在本部分做一个探讨。

??本部分参考了一些其他博客,在文后的参考链接中注明,特此说明。

1、Redis与mysql的区别

??Redis是一种Key-value型的存储数据库,我们自然有一个疑惑,我们早已会用类似于mysql这样的关系型数据库了,那么他们之间有什么区别,为什么还要用Redis。

??(1)数据库类型不同

??mysql是我们熟知的关系型数据库,数据严格存储在表格的行和列中,面向的是结构化的数据。而Redis是一种非关系型数据库,属于一种NoSQL数据库,除了结构化数据,还可以存储半结构化和非结构化的数据,比如我们在数据类型中提到,字符串可以存储任何数据,比如jpg图片或者序列化的对象。

??(2)运行机制不同

??mysql主要用于存放持久化的数据,将数据存放在硬盘中,读取速度比较慢,适合存放大数据。Redis的数据保存在缓存中,缓存的读取速度快,效率高,要存放大量数据需要进行分区和横向扩展。另外,Redis天生就是适合分布式存储的,可以动态的横向扩展。

??mysql在每次访问数据库时,都存在着复杂的I/O操作,在连接数据库上花费大量时间,效率比较慢。Redis的数据本身就在缓存中,可以用于存储使用频繁的热数据,不会产生复杂的I/O。

??(3)面向的需求不同

??mysql面向大量数据的持久化存储,由于关系型数据库的优势,适合用于多表联合查询等。Redis由于缓存容量有限,只可以作为一个减轻数据库压力的缓冲和少量热数据存储的数据库。因此,实际上,很多情况下是mysql和Redis联合使用,redis存储使用频繁的数据,这样减少访问数据库的次数,提高运行效率。

??(4)性能差异明显

??关系型数据库为了维护数据的一致性付出了巨大的代价,读写性能比较差。在面对高并发读写性能非常差,面对海量数据的时候效率非常低。而Nosql存储的格式都是key-value类型的,并且存储在内存中,非常容易存储,而且对于数据的 一致性是 弱要求。Nosql无需sql的解析,提高了读写性能。

2、为什么使用Redis

??关于为什么使用Redis,感觉有一篇博客讲的比较好,这里借用其中的两幅图(参考链接中注明)。

??使用Redis主要考虑到的是两个因素:性能和并发

??(1)高性能

??在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应


技术分享图片

??(2)高并发

??在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。


技术分享图片

3、Redis为什么“快”

??(1) 绝大部分请求是纯粹的内存操作(非常快速)

??(2) 采用单线程,避免了不必要的上下文切换和竞争条件

??(3) 非阻塞多路IO复用

4、Redis的单线程机制

??单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。

??这个可能不太好理解,单线程怎么还比多线程快了呢,这是因为Redis的性能瓶颈在内存的大小和网络的带宽,重点是Redis存储在内存,不涉及I/O操作,(只有在有I/O操作的时候,线程因为I/O而阻塞,此时将CPU让给别的线程会达到比较好的性能),所以Redis几乎不涉及任何的外部I/O,因此,单线程是最快的。


技术分享图片

5、Redis的多路I/O复用

??IO多路复用是用来解决对多个I/O监听时,一个I/O阻塞影响其他I/O的问题,跟多线程没关系。跟多线程相比较,线程切换需要切换到内核进行线程切换,需要消耗时间和资源.而I/O多路复用不需要切换线/进程,效率相对较高,特别是对高并发的应用nginx就是用I/O多路复用,故而性能极佳.但多线程编程逻辑和处理上比I/O多路复用简单.而I/O多路复用处理起来较为复杂。

??这个理解较难,可以参考文后给出的链接。

6、redis的过期策略以及内存淘汰机制

??redis采用的是定期删除+惰性删除策略

??定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。

??如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制

??在redis.conf中有一行配置maxmemory-policy allkeys-lru,该配置就是配内存淘汰策略的。
??1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

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

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

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

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

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

参考链接(本文大多内容参考其他博客,特此注明):

https://www.cnblogs.com/zxh1297/p/9394108.html

https://www.cnblogs.com/bigben0123/p/9115597.html

https://www.jianshu.com/p/9b71f8ee6e28

作者:itcats_cn
来源:CSDN
原文:https://blog.csdn.net/itcats_cn/article/details/82391719

【Redis】四、Redis设计原理及相关问题

原文:https://www.cnblogs.com/gzshan/p/10975129.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!