zoukankan      html  css  js  c++  java
  • redis 的高并发的理解

    redis 的特点:

    • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
    • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
    • Redis支持数据的备份,即master-slave模式的数据备份。

    redis 在并发下出现的情况:

    缓存穿透:

      用户发送数据(一条数据库中存在、redis中不存在的) 到redis中没有就去DB中查,如果DB中没有查询到,就返回给用户;若黑客使用这个漏洞 进行对数据库的攻击就会给数据库击垮。

    解决的办法:

      1、添加过期时间

      2、添加一个布隆过滤器   

      布隆过滤器( 加载120万的数据需要 9秒,)是数据哈希到一个足够大额 bigMap 中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力,但是布隆过滤器有个一误判率是大约是3%

      DB查询到数据为空的时候, 把数据写入到redis中 key对应的value就是空值, 并设置key 的过期时间,设置过期时间最好使用1-5的随机数,

      

    缓存击穿:

      用户发送请数据到redis中 发现redis的数据过期了。这个时候就会去查询数据库, 如果有大量的并发请求,发现有大量的数据在redis中过期了。这个时候就会给DB造成巨大的压力。

      解决的方法:

      1、设置redis中的key 为过期时间为随机数最大不超过5, 

      2、 在访问DB的时候加上锁, 如果是分布式就使用分布式锁。  使用互斥锁  (setNx )

    缓存雪崩:

      当redis中数据在某一个时间段存在大量的过期时间,就会去请求DB 这样会给数据库带来巨大的压力或者是击垮数据库。

    解决方法:

      在访问数据库的时候加锁

      设置队列关系

    缓存预热:

      就系统上线的时候需要把数据库中的数据缓存到redis中,这个样就可以避免用户在查询的数据时候在从数据库中查了。 

    解决的方法:

      1,系统上线后 实现都写好的执行缓存的刷新的页面进行操作。2,也可以手动的更新,3、定时刷新缓存 

    如果缓存的数据不多的话  设置项目启动就可以启动缓存更新。

    缓存更新:

      Redis默认的有6中策略可供选择

         比较常用有两种方案:

      1、定时去清理过期的缓存,

      2、 用户请求过来的时候,发现缓存中的数据过期了,在去数据库查在去根性·更新redis。

    缓存降级

    当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。

    降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。

    以参考日志级别设置预案:

    (1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;

    (2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;

    (3)错误:比如可用率低

    redis  的命令 使用  :  

    与String相关的常用命令:

    • SET:为一个key设置value,可以配合EX/PX参数指定key的有效期,通过NX/XX参数针对key是否存在的情况进行区别操作,时间复杂度O(1)

    • GET:获取某个key对应的value,时间复杂度O(1)

    • GETSET:为一个key设置value,并返回该key的原value,时间复杂度O(1)

    • MSET:为多个key设置value,时间复杂度O(N)

    • MSETNX:同MSET,如果指定的key中有任意一个已存在,则不进行任何操作,时间复杂度O(N)

    • MGET:获取多个key对应的value,时间复杂度O(N)

    与List相关的常用命令:

    • LPUSH:向指定List的左侧(即头部)插入1个或多个元素,返回插入后的List长度。时间复杂度O(N),N为插入元素的数量

    • RPUSH:同LPUSH,向指定List的右侧(即尾部)插入1或多个元素

    • LPOP:从指定List的左侧(即头部)移除一个元素并返回,时间复杂度O(1)

    • RPOP:同LPOP,从指定List的右侧(即尾部)移除1个元素并返回

    • LPUSHX/RPUSHX:与LPUSH/RPUSH类似,区别在于,LPUSHX/RPUSHX操作的key如果不存在,则不会进行任何操作

    • LLEN:返回指定List的长度,时间复杂度O(1)

    • LRANGE:返回指定List中指定范围的元素(双端包含,即LRANGE key 0 10会返回11个元素),时间复杂度O(N)。应尽可能控制一次获取的元素数量,一次获取过大范围的List元素会导致延迟,同时对长度不可预知的List,避免使用LRANGE key 0 -1这样的完整遍历操作。


      应谨慎使用的List相关命令:

    • LINDEX:返回指定List指定index上的元素,如果index越界,返回nil。index数值是回环的,即-1代表List最后一个位置,-2代表List倒数第二个位置。时间复杂度O(N)

    • LSET:将指定List指定index上的元素设置为value,如果index越界则返回错误,时间复杂度O(N),如果操作的是头/尾部的元素,则时间复杂度为O(1)

    • LINSERT:向指定List中指定元素之前/之后插入一个新元素,并返回操作后的List长度。如果指定的元素不存在,返回-1。如果指定key不存在,不会进行任何操作,时间复杂度O(N)

    由于Redis的List是链表结构的,上述的三个命令的算法效率较低,需要对List进行遍历,命令的耗时无法预估,在List长度大的情况下耗时会明显增加,应谨慎使用。

    与Hash相关的常用命令:

    • HSET:将key对应的Hash中的field设置为value。如果该Hash不存在,会自动创建一个。时间复杂度O(1)

    • HGET:返回指定Hash中field字段的值,时间复杂度O(1)

    • HMSET/HMGET:同HSET和HGET,可以批量操作同一个key下的多个field,时间复杂度:O(N),N为一次操作的field数量

    • HSETNX:同HSET,但如field已经存在,HSETNX不会进行任何操作,时间复杂度O(1)

    • HEXISTS:判断指定Hash中field是否存在,存在返回1,不存在返回0,时间复杂度O(1)

    • HDEL:删除指定Hash中的field(1个或多个),时间复杂度:O(N),N为操作的field数量

    • HINCRBY:同INCRBY命令,对指定Hash中的一个field进行INCRBY,时间复杂度O(1)

    应谨慎使用的Hash相关命令:

    • HGETALL:返回指定Hash中所有的field-value对。返回结果为数组,数组中field和value交替出现。时间复杂度O(N)

    • HKEYS/HVALS:返回指定Hash中所有的field/value,时间复杂度O(N)

    上述三个命令都会对Hash进行完整遍历,Hash中的field数量与命令的耗时线性相关,对于尺寸不可预知的Hash,应严格避免使用上面三个命令,而改为使用HSCAN命令进行游标式的遍历,具体请见 

    https://redis.io/commands/scan

    --

    为什么redis是单线程模型也能效率也很高?

      1 纯内存操作

      2 核心是基于非阻塞的 io 多路复用机制

      3 单线程 反而避免了多线程上下文切换的问题。

    redis分布式锁:

    设置分布式锁 set my:lock 随机值 NX PX 30000
    (my 可以用 用户id或者是订单id等,随机值不能重复。NX:存在设置失败,反之就成功,px 设置过期时间)
    释放锁。 就是删除key 是根据随机值, 是根据redis中的随机值和key对应的随机值一致就删除。

  • 相关阅读:
    LeetCode "Jump Game"
    LeetCode "Pow(x,n)"
    LeetCode "Reverse Linked List II"
    LeetCode "Unique Binary Search Trees II"
    LeetCode "Combination Sum II"
    LeetCode "Divide Two Integers"
    LeetCode "First Missing Positive"
    LeetCode "Clone Graph"
    LeetCode "Decode Ways"
    LeetCode "Combinations"
  • 原文地址:https://www.cnblogs.com/yishuo/p/12651439.html
Copyright © 2011-2022 走看看