golang工程中间件——redis常用结构及应用(string, hash, list)-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Redis

命令中心

【golang工程中间件——redisxxxxx】这些篇文章专门以应用为主原理性的后续博主复习到的时候再详细阐述

string结构以及应用

字符数组redis字符串是二进制安全字符串可以存储图片等二进制数据同时也可以存储经过 messagepack 或者 protobuffer 等工具压缩后的二进制数据 内部实际存储根据 string 的数据特征可采用 int 、 embstr 、 raw 存储长度是否能化为整数等条件主要是长度

基础命令

# 设置 key 的 value 值
SET key val
# 获取 key 的 value
GET key
# 执行原子加一的操作
INCR key
# 执行原子加一个整数的操作
INCRBY key increment
# 执行原子减一的操作
DECR key
# 执行原子减一个整数的操作
DECRBY key decrement
# 如果key不存在这种情况下等同SET命令。 当key存在时什么也不做
SETNX key value
# 删除 key val 键值对
DEL key
# 设置或者清空key的value(字符串)在offset处的bit值。
SETBIT key offset value
# 返回key对应的string在offset处的bit值
GETBIT key offset
# 统计字符串被设置为1的bit数.
BITCOUNT key

应用

对象存储

常用存储json字符串或者protobuffer序列化二进制。

SET role:10001 '{["name"]:"mark",["sex"]:"male",["age"]:30}'
GET role:10001
# 固定不变或者几乎不会修改它采用

程序读取后反序列化为对象即可

累加器
# 统计访问数 累计加1
incr accessCount
# 累计加100
incrby accessCount 100
分布式锁

在这里插入图片描述

  • 排他性
  • 定义获取锁行为
  • 定义释放锁行为
# 加锁
setnx lock 1
# 释放锁
del lock
位运算
# 月签到功能 10001 用户id 202107 2021年7月份的签到 7月份的第1天
setbit sign:10001:202107 1 1
# 计算 2021年7月份 的签到情况
bitcount sign:10001:202107
# 获取 2021年7月份 第二天的签到情况 1 已签到 0 没有签到
getbit sign:10001:202107 2

list结构以及应用

首尾相接的双向链表链表首尾操作时间复杂度为O(1) 查找中间元素时间复杂度为O(n)

列表中数据可能会被压缩

  • 元素长度小于 48不压缩
  • 元素压缩前后长度差不超过 8不压缩

基础命令

# 从队列的左侧入队一个或多个元素
LPUSH key value [value ...]
# 从队列的左侧弹出一个元素
LPOP key
# 从队列的右侧入队一个或多个元素
RPUSH key value [value ...]
# 从队列的右侧弹出一个元素
RPOP key
# 返回从队列的 start 和 end 之间的元素 0, 1 2
LRANGE key start end
# 从存于 key 的列表里移除前 count 次出现的值为 value 的元素
LREM key count value
# 它是 RPOP 的阻塞版本因为这个命令会在给定list无法弹出任何元素的时候阻塞连接
# block right pop
BRPOP key timeout #

应用

LPUSH + LPOP
# 或者
RPUSH + RPOP

队列
LPUSH + RPOP
# 或者
RPUSH + LPOP
异步队列

在这里插入图片描述

redis队列存储应用日志再落盘到ES索引中

类似异步队列一些后台服务往redis队列里写日志专门起日志落盘程序读取redis队列中的日志json字符串对象格式化落盘到ES索引中。

阻塞队列blocking queue
LPUSH + BRPOP
# 或者
RPUSH + BLPOP

实际应用过程中需要保证命令的原子性所以需要使用 lua 脚本或者使用 pipeline 命令 + 事 务

# 在某些业务场景下需要获取固定数量的记录比如获取最近50条战绩这些记录需要按照插入的先
后顺序返回
lpush says '{["name"]:"狐金道长", ["text"]:"镇山河!",
["picture"]:["url://image-20230601232741434.jpg", "url://image202306asxx741435.jpg"], timestamp = 1699241288}'
lpush says '{["name"]:"六红军爷", ["text"]:"任驰骋!",
["picture"]:["url://image-20230601134742434.jpg", "url://image20230asff72741436.jpg"], timestamp = 1699241288}'
lpush says '{["name"]:"蹩脚毒萝", ["text"]:"化蝶!",
["picture"]:["url://image-20230601172543434.jpg", "url://image2021060123a41437.jpg"], timestamp = 1699241288}'
lpush says '{["name"]:"sb弓", ["text"]:"我是傻狗",
["picture"]:["url://image-20230601172744678.jpg", "url://image20230601146272741438.jpg"], timestamp = 1699241288}'
# 裁剪最近5条记录 例如聊天记录 
ltrim says 0 4
# 获取队列所有内容
lrange says 0 -1

问题

可能会有很多连接去对list进行操作。但是redis是单线程的只会处理一个命令。但是在这两条命令之间可能会有别的命令对list进行操作。所以需要保证这两个命令一起执行。

# 裁剪最近5条记录 例如聊天记录 
ltrim says 0 4
# 获取队列所有内容
lrange says 0 -1

实际应用过程中需要保证命令的原子性所以需要使用 lua 脚本或者使用 pipeline 命令 + 事 务

hash结构以及应用

字典结构通过 hash 函数来确定节点的位置很多高级语言包含 这个数据结构例如 c++ 中 unordered_mapgo 语言当中的 map 结构

基础命令

# 获取 key 对应 hash 中的 field 对应的值
HGET key field
# 设置 key 对应 hash 中的 field 对应的值
HSET key field value
# 设置多个hash键值对
HMSET key field1 value1 field2 value2 ... fieldn valuen
# 获取多个field的值
HMGET key field1 field2 ... fieldn
# 给 key 对应 hash 中的 field 对应的值加一个整数值
HINCRBY key field increment
# 获取 key 对应的 hash 有多少个键值对
HLEN key
# 删除 key 对应的 hash 的键值对该键为field
HDEL key field

存储结构

当节点数量少的时候且字符串长度小的时候内部采用压缩列表存储否则采用字典实现

10.62.122.23:7002> object encoding MyCart:10001
"ziplist"

应用

存储对象
hmset hash:10001 name qudaodao age 18 sex male
# 与 string 比较
set hash:10001 '{["name"]:"qudaodao",["sex"]:"male",["age"]:18,
["money"]:1000000}'
# 假设现在修改qudaodao的年龄为19岁
# hash:
hset hash:10001 age 19
# string:
get role:10001
# 将得到的字符串调用json.decode解密取出字段修改 age 值
# 再调用json加密
set role:10001 '{["name"]:"qudaodao",["sex"]:"male",["age"]:19}'
购物车
# 将用户id作为 key
# 商品id作为 field
# 商品数量作为 value
# 注意这些物品是按照我们添加顺序来显示的
# 添加商品
hset MyCart:10001 40001 1
lpush MyItem:10001 40001
# 增加数量
hincrby MyCart:10001 40001 1
hincrby MyCart:10001 40001 -1 // 减少数量1
# 显示所有物品数量
hlen MyCart:10001
# 删除商品
hdel MyCart:10001 40001
lrem MyItem:10001 1 40001
# 获取所有物品
lrange MyItem:10001
# 40001 40002 40003
hget MyCart:10001 40001
hget MyCart:10001 40002
hget MyCart:10001 40003

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: goredis

“golang工程中间件——redis常用结构及应用(string, hash, list)-CSDN博客” 的相关文章