Redis 学习笔记

一、简介

1、纯内存操作(理解成容量就是内容条)

2、作为缓存使用(因为内存条操作,比磁盘速度快)

二、 常见命令

类型 命令
string

set、get、mset、mget、setrange、getrange、

incr、decr、incrby、decrby、incrbyfloat、

append、del、strlen、

list

lrange、lindex、llen、

rpush、lpush、linsert、lset

lpop、rpop、lrem、ltrim

blpop、brpop

zset

zadd、zcard、zscore、zcount、zincrby、

zrank、zrevrank、zrange、zrevrange、zrangebyscore、zrevrangebyscore

zrem、zremrangebyrank、zremrangebyscore、

zinterstore、zunionstore、

set

sadd、srem、scard、sismember、srandmember、

spop、smembers

sinter、sunion、sdiff

hash

hset、hget、hgetall、hmget、hmset、hsetnx、

hdel、hlen、hexists、hekys、hvals、hstrlen、

hincrby、hincrbyfloat、

类型 内部编码 备注
string int - embstr - raw

int 或者 str.length=39

list ziplist - linkedlist

64byte 或者 count = 512

list-max-ziplist-entries=512

list-max-ziplist-value=64

zset ziplist - skiplist

64byte 或者 count = 512

zset-max-ziplist-entries=128

zset-max-ziplist-value=64

hash ziplist - hashtable

64byte 或者 count = 512

hash-max-ziplist-entries=512

hash-max-ziplist-value=64

set intset - hashtable

int 或者  count = 512

set-max-intset-entries=512

三、其他功能

功能 备注
慢查询分析

slowlog-log-slower-than 单位:微秒,默认10毫秒,比如keys* 命令会引起慢查询

slowlog-max-len:慢查询日志存储多少条

Redis Shell

redis-cli --slave 把当前客户端模拟成从节点

redis-cli --rdb 生成rdb持久化文件在本地

redis-cli --pipe 命令封装,批量发送

redis-cli --bigkeys 使用scane命令对Redis采样,找出内存占用多的key

redis-cli --eval 执行执行Lua脚本

redis-cli --latency、latency-history、--latency-dist 检测网络延迟

---

redis-benchmark 基准性能测试

Pipeline

Redis命令执行步骤:1、发送命令 2、执行命令 3、返回结果。步骤1-3称为RTT(Round Trip Time,往返时间)

Pipeline的目的就是为了减少N次 RTT

Redis 学习笔记_第1张图片

原生批量命令是原子的,比如mget、mset

Pipeline是非原子的 

事务

multi事务开始,exec事务结束,discard放弃事务、

事务异常的2种处理方式:

1、命令错误不执行,比如set写成sett

2、运行时错误会执行,比如sadd写成zadd

watch某个key,该key变化则事务不执行.

Lua

Lua的优势:原子执行、可以复用、多命令打包可以减少网络开销

数据类型:booleans(布尔)、numbers(数值)、string(字符串)、tables(表格,类似于数组)

执行lua脚本:

redis-cli --eval 字符串,执行脚本,

redis-cli --evalsha SHA字符串,执行对应的lua脚本

redis-cli script load "lua脚本" 把命令加载到Redis内存中,生成sha字符串

redis-cli script exists sha1字符串,判断该lua脚本是否已经加载到内存中了

redis-cli script flush 清除Redis内存中所有Lua脚本

redis-cli script kill 杀掉正在执行的Lua脚本(比如长耗时或者死循环)

Bitmaps

1、Bitmaps不是一种数据结构,实际上就是存放0和1的字符串

2、数组的下标在Bitmaps中叫做偏移量。

---

setbit key offset value 设置数组中的某个下标是0或者1

getbit key offset 或者下标的value

bitcount key [start][end] 获取某个bitcount的1的数量

bitop op destkey key[key ...] 复合操作,op可以是 and、or、not、xor

bitops key value [start] [end] 查看指定范围内targetBit的偏移量

---

BITPO 可以用于以下几个场景:

1、OR 统计某个时间段内的用户活跃度

可以使用 BITOP OR 命令将某个时间段内所有用户的活跃状态合并到一个 key 中,进而使用 BITCOUNT 统计该时间段内活跃用户的数量。

2、AND 实现布隆过滤器

布隆过滤器是一种由一个比特位向量和一系列随机映射函数组成的快速查找算法。可以使用 BITSET 命令将每条数据的多个哈希值对应的二进制序列值设为 1,然后对多个二进制序列使用 BITOP AND 命令, 以判断某个数据是否存在于布隆过滤器中

---

BITPOS 可以用于以下几个场景:

1、统计在线时长

比如,在线游戏中,可以通过记录玩家的登录、退出时间,然后通过对这两个时间点之间的每一分钟(或某个时间间隔)使用 Bitmap 记录玩家是否在线,并且用 BITPOS 命令获取玩家下线时间点之后的第一个 0(即离线时间点),从而计算出玩家的在线时长。

2、统计压缩存储

可以使用 BITPOS 命令查找某个二进制存储空间中最后一个为 0 的位置,并将该位置后的所有位清空,从而实现一种简单的压缩存储方式,节约存储空间。

---

Redis 学习笔记_第2张图片

Bitmap 场景:

  • 统计用户订阅/取消订阅某个频道的状态;
  • 统计某网站某段时间内用户的购买/未购买状态;
  • 统计用户某段时间内的登录/退出状态;
  • 统计某个广告的展示/未展示状态。
HyperLogLog

不是新的数据结构,实际类型为字符串类型

优势:占用空间小,为了计算总数

劣势:统计数量不是100%准确

---

常见命令:

pfadd key element1 [element2 ...] 添加元素

pfcount key 统计key中元素数量,不是100%准确

pfmerge destkey sourcekey[sourcekey ...] 合并去重

Redis 学习笔记_第3张图片

HyperLogLog 场景:

  • 统计网站某个页面的独立访问量;
  • 统计某个品牌的独立消费者数量;
  • 统计某个社交媒体账号的独立观众数量;
  • 统计某个游戏的独立玩家数量。

因为 Bitmap 只能处理二分类状态,因此如果需要处理的数据是多分类状态,如用户等级、网站地域等,就不适合使用 Bitmap。相应地,如果需要精确度较高的计数,不适合使用 HyperLogLog,因为它的误差可能会比较大,不适合要求精度的统计场合。

发布订阅

publish channel1 msg 发布消息

subscribe channel1 [channel2 ...] 订阅多个频道

unsubscribe channel1 [channel2 ...] 取消订阅

psubscribe pattern1 [pattern2] 正则模式订阅N个频道

punsubscribe pattern1 [pattern2] 取消订阅

pubsub channels 查看最少有一个订阅者的频道(活跃频道)

pubsub channels pattern

pubsub numsub channel1 查看channel的消费者数量

pubsub numpat 查看正则模式的消费者数量,对于psubscribe

---

Redis 是一个基于内存的缓存数据库,而 Kafka 是一个分布式的高吞吐量消息系统。二者在设计和应用场景上有较大的差异,因此在消息订阅方面也有一些差别。具体原因如下:

1、内存存储和磁盘存储的区别:

Redis 以内存存储为主,而 Kafka 以磁盘存储为主。内存存储在读取速度和写入速度方面都有很大的优势,而磁盘存储则更适合海量存储和长时间存储。

2、订阅类型的区别:

Redis 基于 Pub/Sub 模式实现订阅,支持消息的发布和订阅,支持多种消息类型,但不支持持久化。而 Kafka 基于发布订阅模式实现订阅,支持各种响应式消息处理,允许多个订阅者同时订阅同一个 topic,支持持久化和重放功能,更加适合于复杂多变的消息场景。

3、可扩展性的不同:

Redis 支持cluster 模式,允许将数据分散到多个节点,并充分利用多台机器的内存容量。但是,当 Redis 集群中某个节点故障时,数据仍然只能从其他节点中恢复,无法像 Kafka 那样快速恢复。而 Kafka 具有很高的可扩展性,支持通过更多的机器添加到组中实现水平扩展,因此也更适合于需要快速适应业务增长的场景。

综上所述,Redis 在消息订阅方面的局限性主要来自其内存存储的特点和 Pub/Sub 模式的限制,以及缺乏持久化和复杂多变的消息处理机制。而 Kafka 则相对更加灵活和可扩展,具有更强大的消息处理和持久化能力,因此也更适合大规模消息场景的处理。

GEO

geo数据类型是zset

 删除GEO的key, zrem cities:localtions

geoadd key longitude latitude member 添加元素(经纬度、城市)

geoadd cities:locatoins 116.28 39.55 beijing 

geopos key member 获取北京的经纬度

geodist key beijing tianjing 获取距离(北京天津之间)

georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key] georadiusbymember key member 

georadius与georadiusbymember的区别在于一个传入的是经纬度,一个是城市

georadiusbymember cities:locations beijing 150 km 找出距离北京150km内的城市

geohash key member 把经纬度转成字符串

--

通常来说,类似高德地图、Google 地图这样的地理位置数据,并不是使用 Redis 进行存储与管理,而是采用专门的地理位置数据库,例如 PostGIS、MongoDB 等。

这些数据库支持空间数据类型,可以用来表示点、线、面等信息,支持空间索引,可以高效地查询区域内的数据。存储经纬度信息通常是使用 Point 等数据类型,将经纬度信息存储为一个二维坐标系中的点。

---

MongoDB 中的 GeoSpatial 索引是一种支持地理位置数据存储和查询的方法,通常用于处理基于地理位置的应用,例如附近的人、地理位置搜索等。与 Redis 中的 Geo 模块不同,MongoDB 中的 GeoSpatial 索引使用 B 树或 R 树等数据结构进行存储和查询,并且支持更灵活的地理查询操作。

具体来说,MongoDB 中的 GeoSpatial 索引支持存储点、线、面等不同类型的地理数据,并支持各种空间查询操作,例如查询指定半径内的点、查询在指定区域内的点、查询最近的点等。与 Redis 不同的是,MongoDB 支持更多种类的地理查询操作,并且查询效率也比 Redis 更高。

此外,MongoDB 还支持基于地理位置的聚合操作,例如计算指定区域内的点的数量、计算指定区域内的点的平均值等。这些聚合操作可以很方便地对地理位置数据进行统计和分析,为基于地理位置的应用提供了更多的支持。

因此,虽然 Redis 中的 Geo 模块也支持存储和查询地理位置数据,但与 MongoDB 相比,MongoDB 在地理查询和聚合操作方面具有更高的灵活性和更高的效率。

四、运维

命令 备注
持久化 save、bgsave(这个会fork子进程去写磁盘,不会阻塞)

LZF 算法是一种无损数据压缩算法,它的压缩速度快、压缩比高、解压速度快,适用于对实时性要求较高的场景。LZF 算法的核心思想是将数据分成多个块,然后对每个块进行压缩,最后将所有压缩后的块拼接起来,形成压缩后的数据。

LZF 算法的压缩过程如下:

  1. 将原始数据分成多个块,每个块的大小为 64KB。

  2. 对每个块进行压缩,压缩后的数据可能比原始数据更小,也可能比原始数据更大。

  3. 如果压缩后的数据比原始数据更小,那么就将压缩后的数据添加到压缩后的数据块中;如果压缩后的数据比原始数据更大,那么就将原始数据添加到压缩后的数据块中。

  4. 重复步骤 2 和步骤 3,直到所有的数据块都被压缩为止。

  5. 将所有压缩后的数据块拼接起来,形成压缩后的数据。

LZF 算法的解压缩过程如下:

  1. 将压缩后的数据分成多个块,每个块的大小为 64KB。

  2. 对每个块进行解压缩,如果当前块是压缩后的数据块,那么就使用 LZF 算法对当前块进行解压缩;如果当前块是原始数据块,那么就直接输出当前块。

  3. 重复步骤 2,直到所有的数据块都被解压缩为止。

  4. 将所有解压缩后的数据块拼接起来,形成原始数据。

需要注意的是,LZF 算法虽然可以在不影响数据完整性的情况下对数据进行压缩,但是压缩后的数据仍然需要进行校验和验证,以确保数据的正确性和完整性。在 Redis 中,LZF 算法被广泛应用于数据的压缩和解压缩,例如在 Redis 的 RDB 持久化和网络传输中,都使用了 LZF 算法对数据进行压缩和解压缩。

五、AOF与RDB对比

RDB AOF
适用场景 备份、全量复制
缺点

1、无法实时持久化(秒级别持久化)

2、重量级操作(每次需要fork子进程)

写入格式 二进制数据格式(如果redis版本变化,可能无法恢复数据) 文本协议格式

你可能感兴趣的:(redis,学习,笔记)