redis的应用

文章目录

    • 一.分布式锁
      • 1.简易版
      • 2.Redisson
    • 二.延时队列
      • 1.异步消息队列
      • 2.加锁冲突失败处理
      • 3.zset实现延迟队列
    • 三.位图
    • 四.HyperLogLog
      • 1.基本命令
      • 2.实现原理
    • 五.布隆过滤器
    • 六.简单限流
      • 1.实现
      • 2.缺点
    • 七.漏斗限流
    • 八.GeoHash
    • 九.scan
      • 1.keys
      • 2.scan

一.分布式锁

可以保证操作的原子性。

1.简易版

使用set key ex 5 nx value,加锁之后如果处理时间太长,锁会自动释放,可能会被下一个线程占用。

可重入性值得是线程在持有锁的情况下再次请求加锁,可以通过ThreadLocal存储当前线程池有的锁的次数

2.Redisson

功能强大:

  • 可重入,使用ThreadLocal存储的重入次数
  • 公平锁,会按照加锁的顺序获取锁
  • 支持锁的到期自动续约,每1/3的国旗时间调用一次,剩余1/3过期时间自动雪月;宕机的话就不自动续约了,释放锁的时候活删除键
  • 支持阻塞式获取锁
  • 释放锁的时候会检查线程是否持有锁,避免死锁

二.延时队列

1.异步消息队列

  • lpush,rpush

  • blpop,brpop

    队列为空时会进入休眠状态,有数据时会立即醒过来,但是闲置过久,服务器会主动断开链接,减少资源占用,因此需要捕获异常,进行重试

2.加锁冲突失败处理

  • 直接抛出异常,稍后重试
  • sleep一会再重试
  • 将请求转至延时队列,过一会再重试

3.zset实现延迟队列

  • 使用zset实现延时队列,将消息序列化为一个字符串,作为value,消息的到期时间作为:当前时间+过期时间

  • 使用多个线程轮询zset获取到期的定时任务,使用zrangebyscore获取,如果获取为空则sleep之后继续获取

三.位图

统计365天的签到记录

1.基本命令

  • setbit

  • getbit

  • bitcount,可以统计1/0的个数

  • bitpos ,定位第一个0/1的位置

  • bitfield,批量对指定位进行处理

    bitfield key set u8 8 97

    从第8位开始,将接下来的8个位用无符号数97代替

    • set
    • get
    • incrby
      • overflow sat,饱和溢出,停留在最大/最小值
      • overflow fail,溢出失败不执行

四.HyperLogLog

统计UV数,误差率0.81%,数量达到阈值后会固定占据12K的空间

1.基本命令

  • pfadd
  • pfcount
  • pfmerge,合并多个pf

2.实现原理

使用多个桶,将数据分布到不同的桶中,然后甲醛平均低位连续0的个数,用以估计数据量

五.布隆过滤器

用来处理大数据量情况下的是否存在的问题,有一定的误判率。如爬虫对URL的去重;垃圾邮件的过滤

1.基本命令

  • bf.add, bf.madd
  • Bf.exists, bf.mexists

2.实现

实际是一个大型的位数组和几个不一样的无偏hash(hash值计算的比较均匀),添加元素时根据key计算hash值,然后按照数组长度取模获取一个位置,然后其他的hash函数也都计算出来位置,将这几个位置都置为1就完成了add操作

3…误判

返回结果是不存在,那么一定是不存在;返回结果是存在,那么可能不存在,影响因素

  • initial_size,预估元素个数,超过时误判率会升高,默认100
  • error_rate, 错误率,越低需要的空间越大,默认0.01

六.简单限流

系统处理能力有限,阻止计划外的请求继续施压。

1.实现

值设定:

  • key:userId + 时/分/秒
  • value:timestamp
  • score:timestamp

操作步骤:

  • add
  • zrangebyscore
  • zcard
  • expire

2.缺点

  • 实现复杂
  • 性能不高

七.漏斗限流

漏斗的剩余容量代表当前行为可持续进行的操作数量,漏斗的流水速率代表该系统允许行为的最大速率。

1.实现

每次流水前都会灌水,更具间隙事件和流水速率计算剩余空间,能腾出多少空间取决于过去留了多少水,空间占用是一个常量,但是该方案不具有原子性

2.可以通过redis-cells组件实现

cl.throttle key 15 30 60,参数分别代表:

  • 15:漏斗容量,初始容量
  • 30 60: 60s允许30次操作

返回值(按顺序):

  • 允许/拒绝
  • 容量
  • 剩余空间
  • 等待时间
  • 完全放空等待时间

八.GeoHash

将地图经纬度坐标映射到一维,通过zset进行维护,将score还原成坐标值就可以得到元素的原始坐标。

1.基本命令

  • geoadd添加

    geoadd company 11 22 juejin

  • geodist计算距离

    geodist company juejin xiaomi km(m,km,ml,ft)

  • geopos、geohash获取位置

    • geopos company juejin:返回经纬度

    • geohash company juejin:返回经纬度的base32编码

  • georadiusbymember获取附件

    georadiusbymember company ireader 20 km count 3 asc

2.数据量大时建议按照地区进行划分(国家、省、市)

九.scan

扫描全局key值

1.keys

支持模式匹配,一次遍历全部数据

2.scan

scan 0 match key99* count 100

参数:

  • cursor:游标,全局hash数组的下标,为0代表遍历结束

  • key的匹配模式

  • 遍历的limit hint,是遍历的卡槽数量,而不是返回的元素个数

遍历顺序:

高位加法,是由rehash的规则导致的,rehash时会将下标为xxx的数据rehash到0xxx和1xxx,而采用高位加法刚好可以顺序遍历到,同时rehash时会遍历新旧两个字典结构汇总返回数据

大key扫描:

redis-cli -h 127.0.0.1 -p --bigkey -i 0.1每隔100条就会休眠0.1秒,避免ops剧烈抬升,但是扫描时间会变长

你可能感兴趣的:(数据库,Redis,读书笔记,redis,数据库,缓存)