Redis 复习一
Redis 复习一
NoSql发展史
Web1.0时代
主要是编辑特征
网站到用户 “单向行为”
Web1.0代表者: 新浪,搜狐,网易
性能要求
简单的静态页面渲染,功能简单单一
Web2.0时代
注重用户交互作用,用户即是网站的浏览者,也是网站内容的创造者
加强网站于用户之间的互动,大数据推荐
实现了网站与用户双向的交流与参与
性能要求
数据库压力越来越大
用Redis当成缓存,来缓解数据库的压力
什么是NoSQL
NoSQL(non-relational) 也称 Not Only SQL
NoSQL仅仅是一个概念,泛指非关系行数据库
区别于关系型数据库他们不保证关系数据库的ACID特征
NoSQl特点
- 关系型数据库的一个补充
应用场景
高并发的读写
海量数据读写
高可扩展性 不限制语言 lua脚本增强
速度快
不适合的场景
需要事务支持时
基于SQL的结构化查询存储,处理复杂关系,需要即席查询(用户自定义查询条件查询)
几种NoSQL数据库简单介绍
memcache(现在有点过时了)
很早出现的NoSQL数据库
数据都在内存中,不支持持久化
支持简单的key-value模式
作为缓存数据库辅助持久化的数据库
Redis
几乎覆盖了memcache的绝大部分功能
数据存储在内存中,支持持久化,主要用作备份恢复
支持简单的key-value模式,支持多种数据结构存储,例:list、set、hash、zset等
作为缓存数据库辅助持久化的数据库
mongoDB
高性能、开源、模式自由的文档型数据库
数据存储在内存中,内存不足,把不常用的数据保存在硬盘中
key-value模式,对value(尤其json)提供丰富的查询功能
支持二进制数据及大型对象
根据数据特点替代RDBMS,成为独立的数据库,或者配合RDBMS,存储特定的数据
列式存储HBase
HBase是Hadoop项目中的数据库,对大量数据进行随机、实时读写操作,目标是处理数据量非常庞大的表,普通计算机处理超过10亿行数据,还可以处理数百万列的数据表,用于大数据
Redis介绍
一个开源的、使用ANSI C语言编写的key-value存储系统(区别于MySQL的二维表格形式存储)
Redis应用场景
取最新N个数据的操作
取网站最新文章,可以将最新的5000条评论ID放在Redis的List集合中,并将超出集合部分从数据库获取
排行榜,取TOP N操作
按顶的次数排序,可以使用Redis的sorted set,将要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可
精准设定过期时间的应用
sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。
计数器应用
Redis的命令都是原子性的,可以利用INCR,DECR命令来构建计数器系统
Uniq操作,获取某段时间所有数据排重值
使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。
实时系统,反垃圾系统
set功能可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等
缓存
将数据直接存放到内存中
Redis特点
高效性 (内存)
Redis读取的速度是30w次/s,写的速度是10w次/s
原子性 (主逻辑线程是单线程)Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。 pipline
支持多种数据结构string(字符串) a->b 配置 name–> xiaobo
elist(列表) a->list 消息队列 msg—>[“hello”,”name”,”xiaobo”]
hash(哈希) a->map 购物车 1—–>[“1”=>”手机”,“2”=>“电脑”]
set(集合) a->set 去重 quchong–>[“北京”,“上海”,“深圳“]
zset(有序集合) a->sorted set 排行榜 top10->[”xxx,xxx“,”xxx,xxx”]
稳定性:持久化,主从复制(集群)
其他特性:支持过期时间,支持事务,消息订阅。
Redis安装
windows版本
解压即可
Linux版本
解压
1 | tar -zxvf redis-6.2.6.tar.gz -C |
C程序运行环境 因为下载的是源码 需要编译
1 | yum -y install gcc-c++ |
tcl
1 | yum -y install tcl |
编译
1 | cd /export/server/redis-6.2.6/ |
创建对应的目录 以及配置对应的conf
1 | cd /export/server/redis-7.0.4/ |
启动
1 | cd /export/server/redis-7.0.4/ |
关闭
1 | bin/redis-cli -h localhost shutdown |
连接
1 | bin/redis-cli -h localhost |
查看是否已经启动
1 | netstat -antp|grep 6379 |
Redis的数据类型
对字符串string的操作
序号 | 命令及描述 | 示例 |
---|---|---|
1 | SET key value 设置指定 key 的值 | 示例:SET hello world |
2 | GET key 获取指定 key 的值。 | 示例:GET hello |
4 | GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 | 示例:GETSET hello world2 |
5 | MGET key1 [key2..] 获取所有(一个或多个)给定 key 的值。 | 示例:MGET hello world |
6 | SETEX key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 | 示例:SETEX hello 10 world3 |
7 | SETNX key value 只有在 key 不存在时设置 key 的值。 | 示例:SETNX name xiaobo |
9 | STRLEN key 返回 key 所储存的字符串值的长度。 | 示例:STRLEN xiaobo |
10 | MSET key value [key value ] 同时设置一个或多个 key-value 对。 | 示例:MSET name1 name2 name3 name4 |
12 | MSETNX key value key value 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 | 示例:MSETNX name1 name2 name3 name4 |
13 | PSETEX key milliseconds value这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 | 示例:PSETEX money 6000 value |
14 | INCR key 将 key 中储存的数字值增一。 | 示例: set number 1 INCR number GET ydlclass7 |
15 | INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) | 示例:INCRBY number 2 get number |
16 | INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment) | 示例:INCRBYFLOAT number 0.8 |
17 | DECR key 将 key 中储存的数字值减一。 | 示例: set number 1 DECR number GET number |
18 | DECRBY key decrement key 所储存的值减去给定的减量值(decrement) | 示例:DECRBY number 3 |
19 | APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。 | 示例:APPEND number hello |
对hash列表的操作
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 2的32 - 1 键值对(40多亿)
序号 | 命令及描述 | 示例 |
---|---|---|
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 |
对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 |
对set集合的操作
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 2的32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
序号 | 命令及描述 | 示例 |
---|---|---|
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 |
对key的操作
序号 | 命令及描述 | 示例 |
---|---|---|
1 | DEL key 该命令用于在 key 存在时删除 key。 | 示例:del number |
2 | DUMP key 序列化给定 key ,并返回被序列化的值。 | 示例:DUMP key1 |
3 | EXISTS key 检查给定 key 是否存在。 | 示例:exists number |
4 | EXPIRE key seconds 为给定 key 设置过期时间,以秒计。 | 示例:expire number 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 |
对ZSet的操作-重要
典型例子:互联网,微博热搜,最热新闻,统计网站pv
Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员
它用来保存需要排序的数据,例如排行榜,一个班的语文成绩,一个公司的员工工资,一个论坛的帖子等。
有序集合中,每个元素都带有score(权重),以此来对元素进行排序
它有三个元素:key、member和score。以语文成绩为例,key是考试名称(期中考试、期末考试等),member是学生名字,score是成绩。
# | 命令及描述 | 示例 |
---|---|---|
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 |
对位图BitMaps的操作
计算机最小的存储单位是位bit,Bitmaps是针对位的操作的,相较于String、Hash、Set等存储方式更加节省空间
Bitmaps不是一种数据结构,操作是基于String结构的,一个String最大可以存储512M,那么一个Bitmaps则可以设置2^32个位
Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量offset
itMaps 命令说明:将每个独立用户是否访问过网站存放在Bitmaps中, 将访问的用户记做1, 没有访问的用户记做0, 用偏移量作为用户的id 。
设置值
1 | SETBIT key offset value |
获取值
1 | GETBIT key offset |
获取Bitmaps指定范围值为1的个数
1 | BITCOUNT key [start end] |
Bitmaps间的运算
1 | BITOP operation destkey key [key, …] |
bitop是一个复合操作, 它可以做多个Bitmaps的and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在destkey中。
1 | bitop and unique:users:and:2022-08-04_05 unique:users:2022-08-03 unique:users:2022-08-04 |
对HyperLogLog结构的操作
HyperLogLog常用于大数据量的统计,比如页面访问量统计或者用户访问量统计。
要统计一个页面的访问量(PV),可以直接用redis计数器或者直接存数据库都可以实现,如果要统计一个页面的用户访问量(UV),一个用户一天内如果访问多次的话,也只能算一次,这样,我们可以使用SET集合来做,因为SET集合是有去重功能的,key存储页面对应的关键字,value存储对应的userid,这种方法是可行的。但如果访问量较多,假如有几千万的访问量,这就麻烦了。为了统计访问量,要频繁创建SET集合对象。
uv: 一个页面被多少个用户访问
pv:一个页面的访问量
Redis实现HyperLogLog算法,HyperLogLog 这个数据结构的发明人 是Philippe Flajolet(菲利普·弗拉若莱)教授。Redis 在 2.8.9 版本添加了 HyperLogLog 结构
1 | help @hyperloglog |
Redis集成的HyperLogLog使用语法主要有pfadd和pfcount,顾名思义,一个是来添加数据,一个是来统计的。
HyperLogLog算法标准误差是 0.81%
pfadd和pfcount常用于统计,需求:假如两个页面很相近,现在想统计这两个页面的用户访问量呢?这里就可以用pfmerge合并统计了
1 | pfadd page1 user1 user2 user3 user4 user5 |
HyperLogLog为什么适合做大量数据的统计
Redis HyperLogLog 是用来做基数统计的算法
Redis Java API操作
- pom.xml
1 | <dependencies> |
- test
1 | public class RedisTest { |
你知道的越多 你不知道的越多 嘿 我是小博 带你一起看我目之所及的世界……
本文标题:Redis 复习一
发布时间:2022年08月05日 - 00:32
最后更新:2022年08月05日 - 00:38
原始链接:https://codexiaobo.github.io/posts/2950641035/
许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。