redis基本功实战

redis9大数据类型

类型介绍
  • string类型 setnx(分布式锁)
  • hash类型 京东早期购物车用过
  • list类型 双端链表结构 可以应用于订阅号消息 商品评论列表等等
  • set类型 可以用来做随机抽奖,随机弹出元素不删除或者出一个删除一个 集合运算:
    • sdiff 集合的差集运算a-b 属于a但是不属于b的共同拥有的元素构成的集合
    • sinter 属于a同时也属于b的共同拥有的元素构成的集合
    • sunion 属于a或者属于b的元素合并后的集合
  • zset类型 主要用作排行榜等
    • zrange获取元素的排名 从小到大
    • zrevrange获取元素的排名 从大到小
    • zrangebyscope根据分数大小获取元素 从小到大
    • zrevrangebyscope根据分数大小获取元素 从大到小
  • bitmap新类型 位图,本质上是数组,由多个二进制位组成,每个二进制位都对应一个偏移量,最大支持2的32次方,极大的节约了存储空间
  • HyPerLogLog新类型 去重统计功能的基数估计算法(可以用来计算UV)
  • GEO新类型 地理位置的处理
名词介绍
  • 什么是uv:
    unique visitor,独立访客,一般理解为客户端ip(需要考虑去重)
  • 什么是pv:
    page view,页面浏览量 不需要去重
  • 什么是dau:
    daily active user 日活跃用户量(反应系统的运营情况 正常是要去重的)
  • 什么是mau:
    monthly active user 月活跃用户量
亿级系统常用的统计类型

必须存的进,取得快,能多维度统计

  • 聚合统计:统计多个集合元素的聚合结果 类似set的集合运算等等
  • 排序统计:用zset
  • 二值统计:用bitmap
  • 基数统计:统计一个集合中不重复元素的个数 去重求和
set类型实用案例
微信小程序抽奖

微信小程序抽奖

微信朋友圈点赞

微信朋友圈点赞数

好友关注社交关系
  • 共同关注的人:用set的集合运算取交集
  • 我关注的人也关注了他
qq推荐可能认识的人

取差集(算法可能更加复杂,先看差集再看交集)

zset类型实用案例
根据商品销售对商品进行排序显示或者热搜

排行榜算法

list做排序的坑

list排序分页的坑

bitmap详细介绍
基本命令
命令作用时间复杂度
setbit key offset val指定key的值的第offset赋值valO(1)
getbit key offset获取指定key的第offset位O(1)
bitcount key start end返回指定key中[start,end]中为1的数量O(n)
bitop operation destkey key对不同的二进制存储数据进行位运算(and,or,not,xor)O(n)
使用场景
  • 用户签到统计
  • 用户月活统计等等
底层编码说明,get命令如何操作

用get命令获取bitmap的key 实质是去拿二进制的ascii编码的对应值

实际上他是用String类型作为底层数据结构实现的一种统计二值状态的数据类型(执行type命令返回string类型)

HyPerLogLog详细解析
概率算法

HyPerLogLog通过牺牲准确率来换取空间,对于不要求绝对准确率的场景下可以使用,因为概率算法不直接存储数据本身.通过一定的概率统计方法预估基数值,同时保证误差在一定范围内,由于又不存储数据故此可以大大的节约内存 他本质上属于一种概率算法的实现

误差仅仅只是0.81%左右 redis之父的解释

经典面试题:为什么redis的最大槽数是16384个

redis集群并没有使用一致性hash而是引入了哈希槽的概念.redis集群有16384个哈希槽,每个key通过crc16校验后对16384取模来决定放置到哪个槽中,集群的每个节点负责一部分hash槽,但是为什么哈希槽的数量是16384(2的14次方)个呢?
crc16算法产生的hash值有16bit,该算法可以产生65536个值,那为什么不用65536而是16384呢?

  1. 如果槽位为65536,发送心跳信息的消息头达到8kb,发送的心跳包过于庞大,在消息头中最占空间的是myslots[cluster_slots/8].当槽位为65536时,这块的大小是:65536/8/1024=8kb,因为每秒钟redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping的消息头太大了,浪费带宽
  2. redis集群主节点数量基本不可能超过1000个.集群节点越多,心跳包的消息体内携带的数据越多,如果节点超过1000个,也会导致网络拥堵,因此redis的作者不建议redis cluster节点数量超过1000个,那么对于节点数1000以内的redis cluster集群,16384个槽位就够用了
  3. 槽位越小,节点少的情况下,压缩比高,容易传输,redis的主节点的配置信息中他所负责的哈希槽是通过bitmap的形式来保存的,在传输过程中会对bitmap进行压缩,但是如果bitmap的填充率slots/N很高的话(N代表节点数),bitmap的压缩率就很低.如果节点数很少,并且哈希槽数量多的话,bitmap的压缩率就很低,所以哈希槽也不宜设置的太大.

redis之父的回答

基本命令
命令作用
pfadd key element将所有元素添加到key中
pfcount key统计key的估算值(不精确)
pgmerge new_key key1 key2合并key至新key
实现原理

在redis里面,每个hyperLogLog键只需要花费12kb内存,就可以计算接近2的64次方个不同元素的基数,这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比.
但是,因为hyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,所以hyperLogLog不能像集合那样,返回输入的各个元素.

为什么是12kb大小

每个桶取6位, 16384*6/8/1024=12kb 每个桶有6位,最大值全部都是1,值就是63

GEO详细介绍
核心思路

核心思想就是将球体转换为平面,区块转换为一个点
主要分为三个步骤

  • 将三维的地球转换为二维的坐标
  • 再将二维的坐标转换为一维的点块
  • 最后把一维的点块转换为二进制在通过base32编码
    全球切割平面图

阿里大神的讲解

基本命令
命令作用
geoadd多个经度(longitude),纬度(latitude),位置名称(member)添加到指定的key
geopos从键里面返回所有给定位置元素的位置(经度和纬度)
geodist返回两个给定位置之间的距离
georadius以给定的经纬度为中心,返回与中心距离不超过给定最大距离的所有位置信息
georadiusbymember跟georadius类似
geohash返回一个或者多个位置元素的geohash表示
georadius详细用法

含义为以给定的经纬度为中心,返回键包含的位置元素中,与中心的距离不超过给定最大距离的所有位置元素((最常用的也是他,可以用做返回半径范围内的酒店或者交友信息等等))
georadius city 116.418017 39.914402 10 km withdist withcoord count 10 withhash desc

  • withdist : 再返回位置元素的同时,将位置元素与中心之间的距离也一并返回.距离的单位和用户给定的范围单位保持一致
  • withcoord : 将位置元素的经度和纬度也一并返回
  • withhash : 以52位有符号整数的形式,返回位置元素经过原始geohash编码的有序集合分值,这个选项主要用于底层应用或者调试,实际中的作用不大
  • count desc : 限定返回的记录数并排序
georadiusbymember

他就是把经纬度换成 具体的地址名称

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

life or die

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值