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


    (六)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

  • 相关阅读:
    利用XAF中的FeatureCenter例子的,直接打开DetailView
    XAF 应用程序模型基础[转]
    XAF 如何给記錄增加版本控制?
    Simpler way to Create a Custom User Control
    建议将小川同志免费租借给欧洲用30年[转]文/端宏斌
    第六集 MSF构思阶段项目团队的组建
    MS_HotFix
    C#域内远程机文件信息注册表访问。
    访问 远程机 盘符 设置
    Silk_ 运行时_控件_属性_捕捉.
  • 原文地址:https://www.cnblogs.com/gzshan/p/10975129.html
Copyright © 2020-2023  润新知