当前位置: 首页 > article >正文

Redis 知识点梳理

第一章 NoSQL数据库发展历史简介

1、 Web的历史发展历程

web1.0时代简介

  • web 1.0是以编辑为特征,网站提供给用户的内容是网站编辑进行编辑处理后提供的,用户阅读网站提供的内容
  • 这个过程是网站到用户的单向行为
  • web1.0时代的代表站点为新浪,搜狐,网易三大门户

性能要求:基本上就是一些简单的静态页面渲染,不会涉及太多复杂业务逻辑,功能简单单一,基本上服务器性能不会有太大压力

web2.0时代简介

  • 更注重用户的交互作用,用户既是网站内容的消费者(浏览者),也是网站内容的制造者
  • 加强了网站与用户之间的互动,网站内容基于用户提供(微博、天涯社区、自媒体) 大数据推荐
  • 网站的诸多功能也由用户参与建设,实现了网站与用户双向的交流与参与
  • 用户在web2.0网站系统内拥有自己的数据,并完全基于WEB,所有功能都能通过浏览器完成。

性能要求:

  • 随着Web2.0时代到来,用户访问量大幅提升,同时产生大量用户数据。加上后来移动设备普及,所有的互联网平台都面临了巨大的性能挑战。数据库服务器压力越来越大
  • 如何应对数据库的压力成为的关键。不管任何应用,数据始终是核心。传统关系型数据库根本无法承载较高的并发,此时人们就开始用Redis当成缓存,来缓解数据库的压力

2、什么是NoSQL

  • NoSQL最常见的解释是"non-relational", 很多人也说它是"Not Only SQL"
  • NoSQL仅仅是一个概念,泛指非关系型的数据库
  • 区别于关系数据库,它们不保证关系数据的ACID特性
  • NoSQL是一项全新的数据库革命性运动,提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入

3、NoSQL的特点 关系型数据库的补充

应用场景:

  • 高并发的读写 10w/s
  • 海量数据读写
  • 高可扩展性 不限制语言、lua脚本增强
  • 速度快

不适用场景:

  • 需要事务支持
  • 基于sql的结构化查询存储,处理复杂的关系,需要即席查询(用户自定义查询条件的查询)政府银行金融项目,还是使用关系型数据库。oracle

4、NoSQL数据库

memcache

  • 很早出现的NoSql数据库
  • 数据都在内存中,一般不持久化
  • 支持简单的key-value模式
  • 一般是作为缓存数据库辅助持久化的数据库

redis介绍

  • 几乎覆盖了Memcached的绝大部分功能
  • 数据都在内存中,支持持久化,主要用作备份恢复
  • 除了支持简单的key-value模式,还支持多种数据结构的存储,比如list、set、hash、zset等。
  • 一般是作为缓存数据库辅助持久化的数据库
  • 现在市面上用得非常多的一款内存数据库

mongoDB介绍

  • 高性能、开源、模式自由(schema free)的文档型数据库
  • 数据都在内存中, 如果内存不足,把不常用的数据保存到硬盘
  • 虽然是key-value模式,但是对value(尤其是json)提供了丰富的查询功能
  • 支持二进制数据及大型对象
  • 可以根据数据的特点替代RDBMS,成为独立的数据库。或者配合RDBMS,存储特定的数据。

列式存储HBase介绍
HBase是Hadoop项目中的数据库。它用于需要对大量的数据进行随机、实时读写操作的场景中。HBase的目标就是处理数据量非常庞大的表,可以用普通的计算机处理超过10亿行数据,还可处理有数百万列元素的数据表。

第二章 Redis介绍

redis官网地址:https://redis.io/
中文网站:http://www.redis.cn/

1、Redis的基本介绍

  • Redis是当前比较热门的NoSQL系统之一
  • 它是一个开源的、使用ANSI C语言编写的key-value存储系统(区别于MySQL的二维表格形式存储)
  • 和Memcache类似,但很大程度补偿了Memcache的不足,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失

2、Redis的应用场景

2.1 取最新N个数据的操作

比如典型的取网站最新文章,可以将最新的5000条评论ID放在Redis的List集合中,并将超出集合部分从数据库获取

2.2 排行榜应用,取TOP N操作

这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,可以使用Redis的sorted set,将要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。

2.3 需要精准设定过期时间的应用

比如可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。

2.4 计数器应用

Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。

2.5 Uniq操作,获取某段时间所有数据排重值

这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。

2.6 实时系统,反垃圾系统

通过上面说到的set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。没有做不到,只有想不到。

2.7 缓存

将数据直接存放到内存中,性能优于Memcached,数据结构更多样化。

3、Redis的特点

  • 高效性 (内存)
    • Redis读取的速度是30w次/s,写的速度是10w次/s
  • 原子性 (主逻辑线程是单线程)
    • Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。 pipline
  • 支持多种数据结构
    • string(字符串) a->b 配置 color–> red
    • list(列表) a->list 消息队列 msg—>[“hello”,“ydlclass”,“itlils”]
    • hash(哈希) a->map 购物车 1----->[“1”=>“剃须刀”,“2”=>“电脑”]
    • set(集合) a->set 去重 quchong–>[“北京”,“山西”,“河北“]
    • zset(有序集合) a->sorted set 排行榜 top10->[”xx拿了金牌,10“,“跑路了,9.5”]
  • 稳定性:持久化,主从复制(集群)
  • 其他特性:支持过期时间,支持事务,消息订阅。

第三章 Redis单机环境安装

1、Windows版Redis安装(了解)

Windows版的安装比较简单,解压Redis压缩包完成即安装完毕,安装的注意事项:

  • 解压的目录不要有中文
  • 目录结构层次不要太深
  • 硬盘空间剩余空间最少要大于你的内存空间,建议20G以上

Redis 目录结构:
在这里插入图片描述

Redis 服务启动与关闭:
1、启动服务器:cmd  redis-server.exe redis.windows.conf
2、默认端口号:6379
3、关闭服务器:直接关闭窗口

在这里插入图片描述
运行【redis-cli.exe】客户端:

在这里插入图片描述

2、Linux版Redis安装(运维)

2.1 下载redis安装包

服务器执行以下命令下载redis安装包

cd  /export/software  
wget  http://download.redis.io/releases/redis-6.2.6.tar.gz
2.2 解压redis压缩包到指定目录

执行以下命令进行解压redis

cd /export/software  
tar -zxvf redis-6.2.6.tar.gz -C
2.3 安装C程序运行环境

执行以下命令安装C程序运行环境

yum  -y install gcc-c++
2.4 安装较新版本的tcl

下载安装较新版本的tcl
使用压缩包进行安装
执行以下命令下载tcl安装包

cd  /export/software  
wget  http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz  


解压tcl  
tar  -zxvf tcl8.6.1-src.tar.gz -C ../server/  
进入指定目录  
cd  ../server/tcl8.6.1/unix/  
./configure  
make && make install

在线安装tcl(推荐)
执行以下命令在线安装tcl

yum -y   install tcl
2.5 编译redis

执行以下命令进行编译:

cd /export/server/redis-6.2.6/  
#或者使用命令 make 进行编译  
make MALLOC=libc     
make test && make install PREFIX=/export/server/redis-6.2.6

修改redis配置文件
执行以下命令修改redis配置文件

cd  /export/server/redis-6.2.6/  
mkdir  -p /export/server/redis-6.2.6/log  
mkdir  -p /export/server/redis-6.2.6/data     

vim  redis.conf  


#  修改第61行  
bind  localhost  
#  修改第128行  后台 
daemonize  yes  
#  修改第163行  
logfile  "/export/server/redis-6.2.6/log/redis.log"  
#  修改第247行  
dir  /export/server/redis-6.2.6/data
2.6 启动redis

执行以下命令启动redis

cd /export/server/redis-6.2.6/  
bin/redis-server redis.conf
2.7 关闭redis
bin/redis-cli  -h localhost shutdown
2.8 连接redis客户端

执行以下命令连接redis客户端

cd  /export/server/redis-6.2.6/  
bin/redis-cli -h localhost

3、Redis Desktop Manager

一款基于Qt5的跨平台Redis桌面管理软件,支持:Windows 7+、Mac OS X 10.10+、 Ubuntu 14+,特点: C++ 编写,响应迅速,性能好。
下载地址:http://docs.redisdesktop.com/en/latest/install/#windows
安装客户端,连接Redis服务:
在这里插入图片描述

备注说明:Redis Desktoo Manager老版本免费,新版本收费

第四章 Redis的数据类型

redis当中一共支持五种数据类型,分别是:

  • string字符串
  • list列表
  • set集合
  • hash表
  • zset有序集合

通过这五种不同的数据类型,可以实现各种不同的功能,也可以应用在各种不同的场景。

所有操作看官网:
在这里插入图片描述

或者符合过人阅读习惯:https://www.runoob.com/redis/redis-keys.html
在这里插入图片描述

1、对字符串string的操作

下表列出了常用的 redis 字符串命令

序号命令及描述示例
1SET key value 设置指定 key 的值示例:SET hello world
2GET key 获取指定 key 的值。示例:GET hello
3GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。示例:GETSET hello world2
4MGET key1 [key2…] 获取所有(一个或多个)给定 key 的值。示例:MGET hello world
5SETEX key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)示例:SETEX hello 10 world3
6SETNX key value 只有在 key 不存在时设置 key 的值示例:SETNX kkclass redisvalue
7STRLEN key 返回 key 所储存的字符串值的长度示例:STRLEN kkclass
8MSET key value [key value ] 同时设置一个或多个 key-value 对示例:MSET kkclass2 kkclassvalue2 kkclass3 kkclassvalue3
9MSETNX key value key value 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。示例:MSETNX kkclass4 kkclassvalue4 kkclass5 kkclassvalue5
10PSETEX key milliseconds value这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。示例:PSETEX kkclass6 6000 kkclass6value
11INCR key 将 key 中储存的数字值增一示例: set kkclass7 1 INCR kkclass7 GET kkclass7
12INCRBY key increment 将 key 所储存的值加上给定的增量值(increment)示例:INCRBY kkclass7 2 get kkclass7
13INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment)示例:INCRBYFLOAT kkclass7 0.8
14DECR key 将 key 中储存的数字值减一示例: set ydlclass8 1 DECR kkclass8 GET kkclass8
15DECRBY key decrement key 所储存的值减去给定的减量值(decrement)示例:DECRBY kkclass8 3
16APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾示例:APPEND kkclass8 hello
1 设置值 获取值
set ydlclass value
get ydlclass
2 mset mget 一次性操作多组数据
mset ydlclass value ydlclass1 value1 ydlclass2 value2
mget ydlclass ydlclass1 ydlclass2
3 没有这个键我们才设置
setnx dlclass value
4 将key的值 加一,减一
incr stock 
decr stock
5设置 a值存活时间5秒,值是b    验证码
setex a 5 b

2、对hash列表的操作

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 2的32 - 1 键值对(40多亿)

下表列出了 redis hash 基本的相关命令:
序号 命令及描述 示例
1 HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。 示例:HSET key1 field1 value1
2 HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。 示例:HSETNX key1 field2 value2
3 HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。 示例:HMSET key1 field3 value3 field4 value4
4 HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。 示例: HEXISTS key1 field4 HEXISTS key1 field6
5 HGET key field 获取存储在哈希表中指定字段的值。 示例:HGET key1 field4
6 HGETALL key 获取在哈希表中指定 key 的所有字段和值 示例:HGETALL key1
7 HKEYS key 获取所有哈希表中的字段 示例:HKEYS key1
8 HLEN key 获取哈希表中字段的数量 示例:HLEN key1
9 HMGET key field1 [field2] 获取所有给定字段的值 示例:HMGET key1 field3 field4
10 HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。 示例: HSET key2 field1 1 HINCRBY key2 field1 1 HGET key2 field1
11 HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 示例:HINCRBYFLOAT key2 field1 0.8
12 HVALS key 获取哈希表中所有值 示例:HVALS key1
13 HDEL key field1 [field2] 删除一个或多个哈希表字段 示例: HDEL key1 field3 HVALS key1
1设置值 获取值
hset user username itlils
hset user age 18
hget user username
2批量
hmset user1 username itnanls age 19
3获取所有的键值对
hgetall user
4获取所有小key
hkeys user
5获取所有值
HVALS user
6删除
hdel user age

3、对list列表的操作

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 2的32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
下表列出了列表相关的基本命令:

序号 命令及描述 示例
1 LPUSH key value1 [value2] 将一个或多个值插入到列表头部 示例:LPUSH list1 value1 value2
2 LRANGE key start stop 查看list当中所有的数据 示例:LRANGE list1 0 -1
3 LPUSHX key value 将一个值插入到已存在的列表头部 示例:LPUSHX list1 value3 LINDEX list1 0
4 RPUSH key value1 [value2] 在列表中添加一个或多个值到尾部 示例: RPUSH list1 value4 value5 LRANGE list1 0 -1
5 RPUSHX key value 为已存在的列表添加单个值到尾部 示例:RPUSHX list1 value6
6 LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素 示例:LINSERT list1 BEFORE value3 beforevalue3
7 LINDEX key index 通过索引获取列表中的元素 示例:LINDEX list1 0
8 LSET key index value 通过索引设置列表元素的值 示例:LSET list1 0 hello
9 LLEN key 获取列表长度 示例:LLEN list1
10 LPOP key 移出并获取列表的第一个元素 示例:LPOP list1
11 RPOP key 移除列表的最后一个元素,返回值为移除的元素。 示例:RPOP list1
12 BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 示例:BLPOP list1 2000
13 BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 示例:BRPOP list1 2000
14 RPOPLPUSH source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 示例:RPOPLPUSH list1 list2
15 BRPOPLPUSH source destination timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 示例:BRPOPLPUSH list1 list2 2000
16 LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 示例:LTRIM list1 0 2
17 DEL key1 key2 删除指定key的列表 示例:DEL list2
1 设置值
lpush list1 1 2 3 4 1
rpush list1 6
2查看数据
lrange list1 0 -1
3 移除数据
lpop list1
rpop list1

4、对set集合的操作

● Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
● Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
● 集合中最大的成员数为 2的32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
下表列出了 Redis 集合基本命令:
序号 命令及描述 示例
1 SADD key member1 [member2] 向集合添加一个或多个成员 示例:SADD set1 setvalue1 setvalue2
2 SMEMBERS key 返回集合中的所有成员 示例:SMEMBERS set1
3 SCARD key 获取集合的成员数 示例:SCARD set1
4 SDIFF key1 [key2] 返回给定所有集合的差集 示例: SADD set2 setvalue2 setvalue3 SDIFF set1 set2
5 SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中 示例:SDIFFSTORE set3 set1 set2
6 SINTER key1 [key2] 返回给定所有集合的交集 示例:SINTER set1 set2
7 SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中 示例:SINTERSTORE set4 set1 set2
8 SISMEMBER key member 判断 member 元素是否是集合 key 的成员 示例:SISMEMBER set1 setvalue1
9 SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合 示例:SMOVE set1 set2 setvalue1
10 SPOP key 移除并返回集合中的一个随机元素 示例:SPOP set2
11 SRANDMEMBER key [count] 返回集合中一个或多个随机数 示例:SRANDMEMBER set2 2
12 SREM key member1 [member2] 移除集合中一个或多个成员 示例:SREM set2 setvalue1
13 SUNION key1 [key2]] 返回所有给定集合的并集 示例:SUNION set1 set2
14 SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中 示例:SUNIONSTORE set5 set1 set2
1添加数据
sadd set1 1 2 3 4 5
2获取数据
smembers set1
3获取成员数量
scard set1
4业务 uv 当天登陆用户数
sadd uv:20220222 001 002 003 002
scard uv:20220222

5、对key的操作

下表给出了与 Redis 键相关的基本命令:
序号 命令及描述 示例
1 DEL key 该命令用于在 key 存在时删除 key。 示例:del ydlclass5
2 DUMP key 序列化给定 key ,并返回被序列化的值。 示例:DUMP key1
3 EXISTS key 检查给定 key 是否存在。 示例:exists ydlclass
4 EXPIRE key seconds 为给定 key 设置过期时间,以秒计。 示例:expire ydlclass 5
6 PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。 示例:PEXPIRE set3 3000
8 KEYS pattern 查找所有符合给定模式( pattern)的 key 。 示例:keys *
10 PERSIST key 移除 key 的过期时间,key 将持久保持。 示例:persist set2
11 PTTL key 以毫秒为单位返回 key 的剩余的过期时间。 示例:pttl set2
12 TTL key 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。 示例:ttl set2
13 RANDOMKEY 从当前数据库中随机返回一个 key 。 示例: randomkey
14 RENAME key newkey 修改 key 的名称 示例:rename set5 set8
15 RENAMENX key newkey 仅当 newkey 不存在时,将 key 改名为 newkey 。 示例:renamenx set8 set10
16 TYPE key 返回 key 所储存的值的类型。 示例:type set10
1删除
del user1
2查看所有的key
keys * 生产环境下,别用
3存在key
exists user1
4存活时间
expire ydlclass 5
5剩余存活时间 登陆续期
pttl user1
6随机获取 key
randomkey

6、对ZSet的操作-重要(热搜)

● Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员
● 它用来保存需要排序的数据,例如排行榜,一个班的语文成绩,一个公司的员工工资,一个论坛的帖子等。
● 有序集合中,每个元素都带有score(权重),以此来对元素进行排序
● 它有三个元素:key、member和score。以语文成绩为例,key是考试名称(期中考试、期末考试等),member是学生名字,score是成绩。
○ 互联网,微博热搜,最热新闻,统计网站pv

命令及描述 示例

1 ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数 向ZSet中添加页面的PV值 ZADD pv_zset 120 page1.html 100 page2.html 140 page3.html
2 ZCARD key 获取有序集合的成员数 获取所有的统计PV页面数量 ZCARD pv_zset
3 ZCOUNT key min max 计算在有序集合中指定区间分数的成员数 获取PV在120-140在之间的页面数量 ZCOUNT pv_zset 120 140
4 ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment 给page1.html的PV值+1 ZINCRBY pv_zset 1 page1.html
5 ZINTERSTORE destination numkeys key [key …] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中 创建两个保存PV的ZSET: ZADD pv_zset1 10 page1.html 20 page2.html ZADD pv_zset2 5 page1.html 10 page2.html ZINTERSTORE pv_zset_result 2 pv_zset1 pv_zset2
7 ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合指定区间内的成员 获取所有的元素,并可以返回每个key对一个的score ZRANGE pv_zset_result 0 -1 WITHSCORES
9 ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员 获取ZSET中120-140之间的所有元素 ZRANGEBYSCORE pv_zset 120 140
10 ZRANK key member 返回有序集合中指定成员的索引 获取page1.html的pv排名(升序) ZRANK pv_zset page3.html
11 ZREM key member [member …] 移除有序集合中的一个或多个成员 移除page1.html ZREM pv_zset page1.html
15 ZREVRANGE key start stop [WITHSCORES] 返回有序集中指定区间内的成员,通过索引,分数从高到低 按照PV降序获取页面 ZREVRANGE pv_zset 0 -1
17 ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 获取page2.html的pv排名(降序) ZREVRANK pv_zset page2.html
18 ZSCORE key member 返回有序集中,成员的分数值 获取page3.html的分数值 ZSCORE pv_zset page3.html
1添加
zadd pv 100 page1.html 200 page2.html 300 page3.html
2查看
zcard pv
3查询指定权重范围的成员数
ZCOUNT pv 150 500
4增加权重
ZINCRBY pv 1 page1.html
5交集
ZADD pv_zset1 10 page1.html 20 page2.html
ZADD pv_zset2 5 page1.html 10 page2.html
ZINTERSTORE pv_zset_result 2 pv_zset1 pv_zset2
6成员的分数值
ZSCORE pv_zset page3.html
7 获取下标范围内的成员。 排序,默认权重由低到高
ZRANGE pv 0 -1
8获取由高到低的几个成员(reverse)使用最多的
效率很高,因为本身zset就是排好序的。
ZREVRANGE key start stop

7、对位图BitMaps的操作

● 计算机最小的存储单位是位bit,Bitmaps是针对位的操作的,相较于String、Hash、Set等存储方式更加节省空间
● Bitmaps不是一种数据结构,操作是基于String结构的,一个String最大可以存储512M,那么一个Bitmaps则可以设置2^32个位
● Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量offset
● BitMaps 命令说明:将每个独立用户是否访问过网站存放在Bitmaps中, 将访问的用户记做1, 没有访问的用户记做0, 用偏移量作为用户的id 。unique:users:2022-04-05 0 1 0 0
7.1 设置值
SETBIT key offset value
setbit命令设置的vlaue只能是0或1两个值
● 设置键的第offset个位的值(从0算起),假设现在有20个用户,uid=0,5,11,15,19的用户对网站进行了访问, 那么当前Bitmaps初始化结果如图所示
● 具体操作过程如下, unique:users:2022-04-05代表2022-04-05这天的独立访问用户的Bitmaps
setbit unique:users:2022-04-05 0 1
setbit unique:users:2022-04-05 5 1
setbit unique:users:2022-04-05 11 1
setbit unique:users:2022-04-05 15 1
setbit unique:users:2022-04-05 19 1
● 很多应用的用户id以一个指定数字(例如10000) 开头, 直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费, 通常的做法是每次做setbit操作时将用户id减去这个指定数字。10000000 10000005 10000011
● 在第一次初始化Bitmaps时, 假如偏移量非常大, 那么整个初始化过程执行会比较慢, 可能会造成Redis的阻塞。
7.2 获取值
GETBIT key offset
获取键的第offset位的值(从0开始算),例:下面操作获取id=8的用户是否在2022-04-05这天访问过, 返回0说明没有访问过。
getbit unique:users:2022-04-05 8

7.3 获取Bitmaps指定范围值为1的个数
BITCOUNT key [start end]
例:下面操作计算2022-04-05这天的独立访问用户数量:
bitcount unique:users:2022-04-05

7.4 Bitmaps间的运算
BITOP operation destkey key [key, …]
bitop是一个复合操作, 它可以做多个Bitmaps的and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在destkey中。
需求:假设2022-04-04访问网站的userid=1, 2, 5, 9, 如图3-13所示:
setbit unique:users:2022-04-04 1 1
setbit unique:users:2022-04-04 2 1
setbit unique:users:2022-04-04 5 1
setbit unique:users:2022-04-04 9 1
例1:下面操作计算出2022-04-04和2022-04-05两天都访问过网站的用户数量, 如下所示。
bitop and unique:users:and:2022-04-04_05 unique:users:2022-04-04 unique:users:2022-04-05
bitcount unique:users:and:2022-04-04_05

例2:如果想算出2022-04-04和2022-04-05任意一天都访问过网站的用户数量(例如月活跃就是类似这种) , 可以使用or求并集, 具体命令如下:
bitop or unique:users:or:2022-04-04_05 unique:users:2022-04-04 unique:users:2022-04-05
bitcount unique:users:or:2022-04-04_05

8、对HyperLogLog结构的操作

8.1 应用场景

HyperLogLog常用于大数据量的统计,比如页面访问量统计或者用户访问量统计。
要统计一个页面的访问量(PV),可以直接用redis计数器或者直接存数据库都可以实现,如果要统计一个页面的用户访问量(UV),一个用户一天内如果访问多次的话,也只能算一次,这样,我们可以使用SET集合来做,因为SET集合是有去重功能的,key存储页面对应的关键字,value存储对应的userid,这种方法是可行的。但如果访问量较多,假如有几千万的访问量,这就麻烦了。为了统计访问量,要频繁创建SET集合对象。

Redis实现HyperLogLog算法,HyperLogLog 这个数据结构的发明人 是Philippe Flajolet(菲利普·弗拉若莱)教授。Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
8.2 UV计算示例
node1.ydlclass.cn:6379> help @hyperloglog

PFADD key element [element …]
summary: Adds the specified elements to the specified HyperLogLog.
since: 2.8.9

PFCOUNT key [key …]
summary: Return the approximated cardinality(基数) of the set(s) observed by the HyperLogLog at key(s).
since: 2.8.9

PFMERGE destkey sourcekey [sourcekey …]
summary: Merge N different HyperLogLogs into a single one.
since: 2.8.9
Redis集成的HyperLogLog使用语法主要有pfadd和pfcount,顾名思义,一个是来添加数据,一个是来统计的。为什么用pf?是因为HyperLogLog 这个数据结构的发明人 是Philippe Flajolet教授 ,所以用发明人的英文缩写,这样容易记住这个语法了。
下面我们通过一个示例,来演示如何计算uv。
node1.ydlclass.cn:6379> pfadd uv user1
(integer) 1
node1.ydlclass.cn:6379> keys *

  1. “uv”
    node1.ydlclass.cn:6379> pfcount uv
    (integer) 1
    node1.ydlclass.cn:6379> pfadd uv user2
    (integer) 1
    node1.ydlclass.cn:6379> pfcount uv
    (integer) 2
    node1.ydlclass.cn:6379> pfadd uv user3
    (integer) 1
    node1.ydlclass.cn:6379> pfcount uv
    (integer) 3
    node1.ydlclass.cn:6379> pfadd uv user4
    (integer) 1
    node1.ydlclass.cn:6379> pfcount uv
    (integer) 4
    node1.ydlclass.cn:6379> pfadd uv user5 user6 user7 user8 user9 user10
    (integer) 1 node1.ydlclass.cn:6379> pfcount uv
    (integer) 10
    HyperLogLog算法一开始就是为了大数据量的统计而发明的,所以很适合那种数据量很大,然后又没要求不能有一点误差的计算,HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,不过这对于页面用户访问量是没影响的,因为这种统计可能是访问量非常巨大,但是又没必要做到绝对准确,访问量对准确率要求没那么高,但是性能存储方面要求就比较高了,而HyperLogLog正好符合这种要求,不会占用太多存储空间,同时性能不错
    pfadd和pfcount常用于统计,需求:假如两个页面很相近,现在想统计这两个页面的用户访问量呢?这里就可以用pfmerge合并统计了,语法如例子:
    node1.ydlclass.cn:6379> pfadd page1 user1 user2 user3 user4 user5
    (integer) 1
    node1.ydlclass.cn:6379> pfadd page2 user1 user2 user3 user6 user7
    (integer) 1
    node1.ydlclass.cn:6379> pfmerge page1+page2 page1 page2
    OK
    node1.ydlclass.cn:6379> pfcount page1+page2
    (integer) 7
    8.3 HyperLogLog为什么适合做大量数据的统计
    ● Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
    ● 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
    ● 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
    什么是基数?
    比如:数据集{1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集{1, 3, 5, 7, 8},基数(不重复元素)为5。基数估计就是在误差可接受的范围内,快速计算基数。

http://www.kler.cn/a/596351.html

相关文章:

  • 如何快速定位高 CPU 使用率的进程
  • git_version_control_proper_practice
  • Linux:基础IO---文件描述符
  • cmakelist中添加opencv
  • 【风信】邮件系统的介绍和使用。
  • Stable Diffusion lora训练(一)
  • 如何防御大模型中的 Prompt 攻击?
  • [蓝桥杯 2023 省 B] 子串简写
  • 深入理解 Spring 框架中的 IOC 容器
  • 六种开源智能体通信协议对比:MCP、ANP、Agora、agents.json、LMOS、AITP
  • 第十六届蓝桥杯模拟二
  • C++面试准备一(常考)
  • JVM垃圾回收笔记01
  • 冒排排序相关
  • 2025年03月10日人慧前端面试(外包滴滴)
  • vue实现图形验证码
  • 过滤器的执行顺序
  • Go语言常用框架及工具介绍
  • 汽车免拆诊断案例 | 2024 款路虎发现运动版车无法正常识别智能钥匙
  • 八股Spring