第二天

内容概要

  • 哈希类型
  • 列表类型
  • 集合类型
  • 有序集合
  • 慢查询
  • pipline与事务
  • 发布订阅
  • Bitmap位图
  • HyperLogLog

哈希类型

  1. hget, hset,hdel

    hget key field  # 获取hash key对应的field的value时间复杂度为o(l)
    
  2. hset key field value

    设置hash key对应的field的value值时间复杂度为o(1)
    
  3. hdel key field

    删除hash key对应的field的值 时间复杂度为o(1)
    
hset user:1:info age 23
hset user:1:info name lqz
hgetall user:1:info
hdel user:1:info age
  1. hexists,hlen

    判断hash key 是否存在field 时间复杂读为o(1)
    
  2. hlen key 获取hash key field的数量 时间复杂度为o(1)

  3.  hexists user:1:info name
     hlen user:1:info  返回数量
    
  4.  hmget key field1 field2 ...fieldN  # 批量获取 hash key的一批field对应的值 时间复杂度是o(n)
     hmset key field1 value1 field2 value2
     # 批量设置hash key的一批field value  时间复杂度是o(n)
     
    
  5. hgetall、hvals、hkeys

    hgetall key  
    # 返回hash key 对应的所用field和value 时间复杂度是o(n)
    
    hvals key
    # 返回hash key 对应的所有field的value 时间复杂度是o(n)
    
    hkey key
    # 返回hash key对应的所有field 时间复杂度是o(n)
    
    小心使用hgetall
    

    计算网站每个用户主页的访问量

    hincrby user:1:info pageview count

    缓存mysql的信息,直接设置hash格式

  6. 其他操作

    hset, hincrby, hincrbyfloat
    hset key field value
    # 设置hash key对应field的
    # value(如果field已存在,则失败),时间复杂度o(1)
    
    hincrby key field intCounter
    # hash key 对应的field的value自增intCouter 时间复杂度o(1)
    hincrbyfloat key field floatCounter
    # hincrby 浮点数 时间复杂度o(1)
    

列表类型

插入操作

rpush  从右侧插入
rpush key value1 value2 ... valueN
时间复杂度为o(1~n)
lpush  从左测插入
linsert
linsert key before|after value newValue
#从元素value的前或后插入newValue 时间复杂度o(n),需要遍历列表
linsert listkey before b java
linsert listkey after b php

# 删除操作
lpop key # 从列表左侧弹出一个item 时间复杂度o(1)

rpop key # 从列表右侧弹出一个item 时间复杂度o(1)

lrem key count value
# 根据count值, 从列表中删除所有value相同的项 时间复杂度o(n)

1 count>0 从左到右,删除最多count个value相等的项
2 count<0 从右向左,删除最多Math.abs(count)个value相等的项
3 count=0 删除所有value相等的项
lrem listkey 0 a  # 删除列表中所有值a
lrem listkey -1 c  # 从右侧删除1个c

ltrim key start end  # 按照索引范围修剪列表o(n)
ltrim listkey 1 4   # 只保留下表1--4的元素


# 查询操作
lrange key start end  # 包含end获取列表指定索引范围所有item o(n)
lrange listkey 0 2
lrange listkey 1 -1   # 获取第一个位置倒数第一个位置的元素

lindex key index  # 获取列表指定索引的item o(n)
lindex listkey 0 
lindex listkey -1

llen key  # 获取列表长度

# 修改操作
lset key index newValue  # 设置列表指定索引值为newValue o(n)

lset listkey 2 ppp     # 把第二个位置设为ppp



实战

实现timeLine功能,时间轴,微博关注的人,按时间轴排列,在列表中放入关注的人的微博的即可

其他操作

blpop  key timeout
# lpop的阻塞版,timeout是阻塞超时 时间,timeout=0为不阻塞o(1)

brpop key timeout
# rpop的阻塞版,timeout是阻塞超时时间,timeout=0 不阻塞o(1)

要实现栈的功能

lpush+lpop

实现队功能

lpush+rpop

固定大小的列表

lpush+ltrim 

消息队列

lpush+brpop

集合类型

sadd key element
# 向集合key添加elemnt 如果element存在,添加失败  o(1)

srem key element
# 从集合中的element移除掉 o(1)
scard key  # 计算集合大小
sismember key element  # 判断element是否在集合中
srandmember key count
# 从集合中随机取出count个元素,不会破坏集合中的元素

spop key  # 从集合中随机弹出一个元素
smembers key 
# 获取集合中所有元素,无需,小心使用,会阻塞住

sdiff user:1follow user:2:follow
# 计算user:1:follow 和 user:2:follow的差集

sunion user:1:follow user:2:follow
# 计算user:1:follow和user:2:follow的并集

sdiff|sinter|suion + store destkey...
# 将差集,交集,并集结果保存在destkey集合中

应用场景

去重场景

抽奖系统:通过spop来弹出用户的id,活动取消,直接删除,点赞,点踩,喜欢等,用户如果点了赞,就把用户id放到该条记录的集合中

标签:给用户/文章等添加标签,sadd user:1:tags 标签1 标签2 标签3

给标签添加用户,关注该标签的人有哪些

共同好友:集合间的操作

有序集合(zset)

特点:不能重复 有一个分值字段,来保证顺序

key           score               value
user:ranking      1                 lqz
user:ranking	   99                lqz2
user:ranking	   88                lqz3

集合有序集合

集合:无重复元素,无序,element

有序集合:无重复元素,有序,element+score

列表和有序集合

列表:可以重复,有序,element

有序集合:无重复元素,有序,element+score

API使用

zadd key score element  # score可以重复,可以多个同时添加,element不能重复 o(logn)
zrem key element # 删除元素,可以多个同时删除o(1)
zscore key element # 获取元素的分数o(1)
zincrby key increScore element  # 增加或减少元素的分数o(1)
zrank key element # 返回element元素的排名(从小到大排)
zrank key 0 -1  # 返回排名,不带分数 o(log(n)+m) n是元素个数,m是要获取的指
zrange player:rank 0 -1 withscores  # 返回排名,带分数

zrangebyscore key minScore maxScore
# 返回指定分数范围内的升序元素 o(log(n)+m) n是元素个数, m是要获取的值
zrangebyscore adscore 90 210 withscores
# 获取90分到210分的元素
zcount key minScore maxScore
# 返回有序集合内在指定分数范围内的个数o(log(n)+m)
zremrangebyrank adscore 1 2 
删除升序排名中1到2的元素

zremrangebyscore key minScore maxScore
删除指定分数内的升序元素o(log(n)+m)

zremrangebyscore adscore 90 100
删除分数90到210之间的元素

实战

排行榜:音乐排行榜,销售榜,关注榜,游戏排行榜

其他操作
zrevrank  # 返回某个元素从高到低排序顺序
zrevrank adscore lqz  返回lqz 按分数降序排名
zrevrange  # 从高到低排序取一定范围
zrevrangebyscore  # 返回指定分数范围内的降序元素
zinterstore  # 对两个有序集合交集
zunionstore  # 对两个有序集合求并集

慢查询

单线程架构,命令一个个执行,会有长慢命令,造成整个redis的阻塞

redis提供一种方式,可以记录长慢命令【放到慢查询队列中】,用于后续的排查修改工作

配置慢查询

-slowlog-max-len:慢查询队列的长度
slowly-log-slower-than:超过多少微妙,就算命令们就会记录到慢查询队列中
    

实战

config set slowlog-log-slower-than 0

config set slowlog-max-len 100
config rewrite
# 写了永久生效,如果不写,只是暂时生效

# 查看慢查询队列
slowlog len  # 获取慢查询队列长度
slowlog reset  #  清空慢查询队列
slowlog get   # 获取慢查询队列的所有命令

pipeline与事务

Redis的pipline(管道)功能在命令行中没有,但redis是支持pipline的,而且在各个语言版的client中都有相应的实现(Redis模块)

将一批命令:批量打包,在redis服务端批量计算(执行),然后把结果批量返回1次pipeline(n条命令)=1次网络时间+n次命令时间

import redis
pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
r = redis.Redis(connection_pool=pool)
# 创建pipline
pipe = r.pipeline(transaction=True)
# 开启事务
pipe.multi()
pipe.set("name", "lqz")
# 其他代码,可能出现异常
pip.set('role','nb')
pipe.execute()
redis原生实现事务   实现事务mutil
1  mutil 开启事务,放到管道中一次性执行
multi   # 开启事务
set name lqz
set age  18
exec
2 模拟实现乐观锁  watch+multi实现乐观锁
在开启事务之前,先watch
watch age
multi
decr age
exec

另一台机器

multi
decr age
exec  先执行,上面的执行就会失败(乐观锁,被watch的事务不会执行成功)

发布订阅

发布订阅是 观察者模式:只要订阅了某个东西,这个东西发送变化,我们就能收到

发布者发布了消息,所有的订阅者都可以收到,就是生成者消费者模型(后订阅了,无法获取历史消息)

一个客户端发送消息
publish lqz hello  # 只要订阅者,客户端发送消息,所有订阅者都能收到

另外两个客户端,订阅频道,等待接收消息
subscribe lqz

查看两个客户端,订阅频道,等待接收消息
subscribe lqz 

查看某个频道有几个订阅者
pubsub numsub lqz

列出活跃的频道
pubsub channels

发布订阅和消息队列
发布订阅数全收到,消息队列有个抢的过程,只有一个抢到

Bitmap位图

Bitmap位图:是字符串类型,但是以二进制形式存储的,获取,设置某个二进制位的

set hello big
getbit hello 0/1/2 返回比特位是0或1

setbit hello 7 1  把第7,也就是8个比特位设置为1
big就变成了cit
bitcount hello 0 1 字节数 返回8

独立用户统计
假设:1亿用户,5千万活跃用户  统计今天活跃用户是多选 用户iduserid是整形,32位
int32 类型  4个字节表示一个数字---》正负 2的31次方-1的范围

方式一:登录,把id放到集合中---》统计集合大小
方式二:登录,操作位图,把id对应的数字设置为1,以后统计1的个数

HyperLogLog

redis中支持这种算法,基于HyperLogLog算法:极小的空间完成独立数量统计很类似与布隆过滤器

pfadd key element  # 向hyperloglog添加元素,可以同时添加多个
pfcount key  # 计算hyperloglog 独立总数
pfadd uuids  "uuid1" "uuid2" "uuid3" # 向uuids添加3个uuid
pfcount uuids  # 返回4

# 也可以做独立用户统计
posted @ 2023-04-24 19:51  可否  阅读(6)  评论(0)    收藏  举报