Redis4 - 数据特性

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/njys1/article/details/82795877
  • 位图
  • 设置键的过期时间
  • 排序
  • pipeline
  • redis事务
  • 发布订阅
  • 使用lua脚本

位图

  1. 位图的底层数据实现是字符串
  2. setbit 设置比特位
     eg. setbit "user_reading" 400 1
     设置相应的bit位

     gitbit "user_reading" 400
     获取bit位

     bitcount "user_reading" 
     获取bit位设置的比率

     位图支持 and、or、xor、和 not 四种操作

     当数据需要进行位运算、比如获取 做了A同时做了B事件的人、可以使用位图进行数据存储

     加入、有20亿个数据需要存储、位图实现需要分配 20亿个比特位、约占用250MB大小的空间
     若、20亿个人中、只有16亿个人使用该功能、那么使用set实现的成本是?
     11600000000*8/1024/1024/1024 约12G内存

     但是、如果使用的人数比较少呢 ?
     假如只有2000w的人使用、仅仅需要约 20000000*8/1024/1024 = 160M的空间、使用set会更好一些

     还有问题、如果是稀疏存储、使用位图、当偏移量比较大的时候、可能会造成redis阻塞

设置键的过期时间

    expire key {{time}} 将key的过期时间设置为{{time}}s

    这种主动设置键的过期时间的行为、称为被动过期
    对于那些已经过期、但暂时不会被访问到的key、redis本身还会定期的按照指定算法来删除的策略
    eg. redis会随机选择20个设置了过期时间的key、若这20个key中、已过期的键会被立即删除
        若选中的键中有超过25%的键已过期、则redis会再次随机选取20个key并重复这个过程
        默认上述过程每秒运行10次、(可通过配置文件的hz来配置)

排序

    对集合中的元素进行排序、可以使用sort
    sort setkey 默认是升序排序、加上desc可以倒序排
    sort sortkey alpha 按照字典序排序
    limit 可以指定每次返回的元素个数

    sort 的时间复杂度是 O(N+M*log(M)) 其中N是list的长度或者集合中元素的个数、M是要返回的元素的个数、
    所以、使用sort还是要谨慎的、大量数据排序时可能会造成redis服务器的性能降低

pipeline

    eg. 
    >> cat pip.txt
    set mykey val
    sadd myset val1 val2
    get mykey
    scard myset

    pipeline 其实是将多个命令、一起发送请求
    可以通过resp协议把所有命令一起发送到server

redis事务

    场景:对于秒杀类的设计、超卖经常是比较难解的问题
    原因:获取计数器的时候涉及竞态、计数器的值也许对于业务场景是有效的(>0)、
    但是在减少计数器之前、可能已经有其它请求修改了这个值

    方案之一:
    可以使用redis的事务解决、对某一个键使用watch设置一个标志、该标志用来判断在执行
    exec命令之前是否有其它命令修改了key、若已修改、则丢弃整个事务、可以认为业务失败

    redis事务的失败
    1. 命令语法有错误、在入队时就能发现、整个事务会快速回滚、事务中的所有命令都不执行
    2. 所有命令都已入队、执行过程中发生了错误、发生错误之后的命令会继续执行、整个事务不会回滚

发布订阅

    publish {{channel-name}} {{msg}} 向某个频道发送msg
    pubsub channels 查看当前活跃的频道
    subscribe {{channel-name}} 订阅某个频道、可以是多个

    当没有活跃的订阅者时、频道将会被删除
    注:redis相关的pubsub机制无持久化机制、若有意外导致server问题、消息均会全部丢失
       所以redis的pubsub功能不保证消息可靠性、但速度还是很快的

使用lua脚本

    redis脚本和事务都可以保证一组操作原子化的执行、
    与redis事务类似、我们必须保证lua脚本的执行时间、在执行lua脚本期间、redis服务器不能执行其它命令
    所以必须保证lua脚本尽可能快的执行完、默认情况下lua脚本的执行时间大于限制(默认5s)时、redis.conf中lua-time-limit 指定、我们可以使用script kill来将其终止
    若、已经调用了任何写入相关的命令、就必须采用shutdown nosave来关闭redis server以终止脚本运行
    若某个lua脚本的执行时间小于限制值时、使用script kill命令则会被阻塞、直到脚本执行超时

    注意:redis脚本只是被保存在redis server的缓存中、重启失效、必须在重启redis之后重新加载lua脚本

    可以使用redis的 --ldb 选项来调试lua脚本

    可能我们会有个疑惑、查看lua脚本中的值的时候、为什么不直接在lua脚本中使用print打印呢 ?
    因为server运行在deamon模式下时、print函数生成的消息会在redis-server进程的stdout中、
    而stdout消息会被丢弃

猜你喜欢

转载自blog.csdn.net/njys1/article/details/82795877