一些小问题

Redis一共有几种数据类型?(注意是数据类型不是数据结构)

一共是八种,String、Hash、Set、List、Zset、Hyperloglog、Geo、Streams。

为什么要把数据放在内存中?

内存的速度更快,10W QPS

减少计算的时间,减轻数据库压力

如果是用内存的数据结构作为缓存,为什么不用HashMap或者Memcached?

更丰富的数据类型

支持多种编程语言

功能丰富:持久化机制、内存淘汰策略、事务、发布订阅、pipeline、LUA

支持集群、分布式

Memcached和redis的区别是什么?

Memcached只能存储KV、没有持久化机制、不支持主从复制、是多线程的。

Redis Key的最大长度限制是512M,值的限制不同,有的是用长度限制的,有的是用个数限制的。

关于其他有趣的 Reids 的内容可以移步这儿:https://www.cnblogs.com/zwtblog/tag/Redis/

String

get和set命令就是String的操作命令,Redis的字符串被叫做二进制安全的字符串(Binary-safe strings)。

String可以存储三种类型,INT(整数)、float(单精度浮点数)、string(字符串)

操作命令

# 存值(如果对同一个key set多次会直接覆盖旧值)
set jack 2673
# 取值
get jack
# 查看所有键
keys *
# 获取键总数(生产环境数据量大,慎用)
dbsize
# 查看键是否存在
exists jack
# 删除键
del jack tonny
# 重命名键
rename jack tonny
# 查看类型
type jack
# 获取指定范围的字符
getrange jack 0 1
# 获取值长度
strlen jack
# 字符串追加内容
append jack good
# 设置多个值(批量操作,原子性)
mset jack 2673 tonny 2674
# 获取多个值
mget jack tonny
# 设置值,如果key存在,则不成功
setnx jack shuaige
# 基于此实现分布式锁
set key value [expiration EX seconds|PX milliseconds][NX|XX]
# (整数)值递增(值不存在会得到1)
incr jack
incrby jack 100
# (整数)值递减
decr jack
decrby jack 100
# 浮点数增量
set mf 2.6
incrbyfloat mf 7.3

应用场景

1、缓存

String类型,这是最常用的,可以缓存一些热点数据,比如首页新闻,可以显著提升热点数据的访问速度,同时减轻DB压力。

2、分布式数据共享

String 类型,因为Redis是分布式的独立服务,可以在多个应用之间共享。

例如:分布式Session

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

3、分布式锁

详情见博客:https://www.cnblogs.com/zwtblog/p/15185894.html

4、全局ID

INT类型,INCRBY,利用原子性

incrby userid 1000(分表分库的场景,一次性拿一段)

5、计数器

INT类型,INCR方法

例如:文章的阅读量,微博点赞数,允许一定的延迟,先写入Redis再定时同步到数据库

6、限流

INT类型,INCR方法

以访问者的IP和其他信息作为key,访问一次增加一次计数,超过次数则返回false。

Hash

这样也便于集中管理,划分的粒度不同,可以按照实际场景,key 的过期时间,灵活度考虑选取哪一种存储方式。

Hash用来存储多个无序的键值对,最大存储数量2^32-1(40亿左右)。

优点:

  1. 把所有相关的值聚集到一个Key中,节省内存空间
  2. 只使用一个Key,减少Key冲突
  3. 当需要批量获取值的时候,只需要使用一个命令,减少内存/IO/CPU的消耗

缺点:

  1. Field不能单独设置过期时间
  2. 需要考虑数据量分布的问题(field非常多的时候,无法分布到多个节点)

操作命令

# 设置、批量设置值
hset h1 f 6
hset h1 e 5
hmset h1 a 1 b 2 c 3 d 4
# 取值
hget h1 a
# 批量取值
hmget h1 a b c d
# 获取所有field
hkeys h1
# 获取所有field的值
hvals h1
# 返回哈希表中,所有的字段和值
hgetall h1
# 删除field
hdel h1 a
# 获取哈希表中字段的数量
hlen h1

应用场景

String可以做的事情,Hash都可以做。

再补充一个场景,购物车

List

存储有序的字符串(从左到右),元素可以重复,最大存储数量2^32-1(40亿左右)。

操作命令

# 左推
lpush queue a
lpush queue b c
# 右推
rpush queue d e
# 左边移除并返回列表的第一个元素
lpop queue
# 右边移除并返回列表的第一个元素
rpop queue
# 通过索引获取列表中的元素
lindex queue 0
# 返回列表中指定区间内的元素
lrange queue 0 -1

应用场景

1、列表

例如用户的消息列表、网站的公告列表、活动列表、博客的文章列表、评论列表等,通过 LRANGE 取出一页,按顺序显示。

2、队列/栈

List还可以当做分布式环境的 队列 / 栈 使用。

队列:先进先出,rpush 和 blpop

栈:先进后出,rpush 和 brpop

这里介绍两个阻塞的弹出操作:blpop/brpop,可以设置超时时间(单位:秒)

blpop:blpop key1 timeout,
移出并获取列表的第一个元素,
如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 brpop:brpop key1 timeout,
移出并获取列表的最后一个元素,
如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

Set

Set 存储 String 类型的无序集合,最大存储数量 2^32-1(40亿左右)。

操作命令

# 添加一个或多个元素
sadd myset a b c d e f g
# 获取所有元素
smembers myset
# 统计元素个数
scard myset
# 随机获取一个元素
srandmember myset
# 随机弹出一个元素
spop myset
# 移除一个或者多个元素
srem myset d e f
# 查看元素是否存在
sismember myset a
# 获取差集
sdiff set1 set2
# 获取交集
sinter set1 set2
# 获取并集
sunion set1 set2

应用场景

1、抽奖

随机获取元素:spop myset

2、点赞、签到、打卡

我们以微博举例子,假设这条微博的ID是t1001,用户ID是u6001,

用  dianzan:t1001  来维护  t1001  这条微博的所有点赞用户。

点赞了这条微博:sadd dianzan:t1001 u6001
取消点赞:srem dianzan:t1001 u6001
是否点赞:sismember dianzan:t1001 u6001
点赞的所有用户:smembers dianzan:t1001
点赞数:scard dianzan:t1001 比关系型数据库简单了许多。

3、商品标签

用 tags : i8001 来维护商品所有的标签。

sadd tags:i8001 画面清晰细腻

sadd tags:i8001 真彩清晰显示屏

sadd tags:i8001 流畅至极

4、商品筛选

华为P50上线了,支持民族品牌,加到各个标签中去。

sadd brand:huawei p50

sadd os:android p50

sadd screensize:6.0-6.24 p50

买的时候筛选,牌子是华为,操作系统是安卓,屏幕大小在6.0-6.24之间的,取交集:

sinter brand:huawei os:android screensize:6.0-6.24

ZSet

sorted set 存储有序的元素。每个元素都有个 score,按照 score 从小到大排序。

score 相同时,按照 key 的ASCII码排序。

操作命令

# 添加元素
zadd myzset 10 java 20 php 30 ruby 40 cpp 50 python
# 获取全部元素
zrange myset 0 -1 withscores
zrevrange myzset 0 -1 withscores
# 根据分数区间获取元素
zrangebyscore myzset 20 30
# 移除元素(也可以根据score rank删除)
zrem myzset php cpp
# 统计元素个数
zcard myzset
# 分值增加
zincrby myzset 5 python
# 根据分值min和max统计个数
zcount myzset 20 60
# 获取python排名
zrank myzset python
# 获取元素分数
zscore myzset python

应用场景

1、排行榜

今天是2021年5月23号,建一个 key 为 hotSearch:20210523 的 zset。

这条新闻的id是n1234,每点击一下:zincrby hotSearch:20210523 1 n1234

获取热搜排行榜前十条:zrevrange hotSearch:20210523 0 10 withscores

BitMaps

BitMaps是在字符串类型上定义的位操作,一个字节由8个二进制位组成。

操作命令

# 设置字符串key为k1,value为mic
set k1 mic
# 取k1的第七位,结果是0
getbit k1 6
# 取k1的第八位为0,此时的ASCII码是108,对应字母是l
setbit k1 7 0
# 所以取出来值为lic
get k1
# 统计二进制中1的个数,一共是12个
bitcount k1
# 获取第一个1或者0的位置
bitpos k1 1
bitpos k1 1
BITOP AND destkey key [key ...],对一个或多个key求逻辑并,并将结果保存到 destkey。

BITOP OR destkey key [key ...],对一个或多个key求逻辑或,并将结果保存到 destkey。

BITOP XOR destkey key [key ...],对一个或多个key求逻辑异或,并将结果保存到 destkey。

BITOP NOT destkey key,对给定key求逻辑非,并将结果保存到 destkey。

应用场景

1、连续在线用户

setbit firstday 0 1 //设置第一天uid是0的用户登录
setbit firstday 1 0 //设置第一天uid是1的用户未登录
setbit firstday 2 1 //设置第一天uid是2的用户登录
...
setbit secondday 0 0 //设置第二天uid是0的用户未登录
setbit secondday 1 1 //设置第二天uid是1的用户登录
setbit secondday 2 1 //设置第二天uid是2的用户登录
... //以此类推 那么在算连续七天在线用户就是:
BITOP AND 7_both_online_users firstday secondday thirdday fourthday fifthday sixthday seventhday

2、应用访问统计

3、在线用户统计

Hyperloglog

Hyperloglog 提供了一种不太精确的基数统计方法,用来统计一个集合中不重复的元素个数,

在 Redis 中实现的 Hyperloglog,只需要12k内存就能统计2^64个数据。

    public static void main(String[] args) {
Jedis jedis = new Jedis("39.103.144.86", 6379);
float size = 100000;
for (int i = 0; i < size; i++) {
jedis.pfadd("hll", "hll-" + i);
}
long total = jedis.pfcount("hll");
System.out.println(String.format("统计个数: %s", total));
System.out.println(String.format("正确率: %s", (total / size)));
System.out.println(String.format("误差率: %s", 1 - (total / size)));
jedis.close();
}

操作命令

PFADD key element [element ...]
添加指定元素到 HyperLogLog 中。 PFCOUNT key [key ...]
返回给定 HyperLogLog 的基数估算值。 PFMERGE destkey sourcekey [sourcekey ...]
将多个 HyperLogLog 合并为一个 HyperLogLog

应用场景

1、统计网站的UV,或者应用的日活、月活,存在一定的误差。

Geo

操作命令

# 存经纬度
geoadd location 121.445 31.213 shanghai
# 取经纬度
geopos location shanghai

应用场景

1、增加地址位置信息、获取地址位置信息

2、计算两个位置的距离

3、获取指定范围内的地理位置集合

    public static void main(String[] args) {
Jedis jedis = new Jedis("39.103.144.86", 6379);
Map<String, GeoCoordinate> geoMap = new HashMap<>();
GeoCoordinate coordinate = new GeoCoordinate(121.445, 31.213);
geoMap.put("shanghai", coordinate);
jedis.geoadd("positions", geoMap);
System.out.println(jedis.geopos("positions", "shanghai"));
jedis.close();
}

Streams

Redis Stream 是 Redis 5.0 版本新增加的数据结构。

Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。

简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。

Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容:

每个 Stream 都有唯一的名称,它就是 Redis 的 key,在我们首次使用 xadd 指令追加消息时自动创建。

上图解析:

  • Consumer Group :消费组,使用 XGROUP CREATE 命令创建,一个消费组有多个消费者(Consumer)。
  • last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
  • pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符)。

操作命令

消息队列相关命令:
XADD - 添加消息到末尾
XTRIM - 对流进行修剪,限制长度
XDEL - 删除消息
XLEN - 获取流包含的元素数量,即消息长度
XRANGE - 获取消息列表,会自动过滤已经删除的消息
XREVRANGE - 反向获取消息列表,ID 从大到小
XREAD - 以阻塞或非阻塞方式获取消息列表 消费者组相关命令:
XGROUP CREATE - 创建消费者组
XREADGROUP GROUP - 读取消费者组中的消息
XACK - 将消息标记为"已处理"
XGROUP SETID - 为消费者组设置新的最后递送消息ID
XGROUP DELCONSUMER - 删除消费者
XGROUP DESTROY - 删除消费者组
XPENDING - 显示待处理消息的相关信息
XCLAIM - 转移消息的归属权
XINFO - 查看流和消费者组的相关信息;
XINFO GROUPS - 打印消费者组的信息;
XINFO STREAM - 打印流信息

应用场景

应用场景小结

缓存======提升热点数据的访问速度

共享数据======数据的存储和共享的问题

全局ID======分布式全局ID的生成方案(分库分表)

分布式锁======进程间共享数据的原子操作保证

在线用户统计和计数

队列、栈======跨进程的队列/栈

消息队列======异步解耦的消息机制

服务注册与发现======RPC通信机制的服务协调中心(Dubbo支持Redis)

购物车

新浪用户消息时间线

抽奖逻辑(礼物、转发)

点赞、签到、打卡

商品标签

用户(商品)关注(推荐)模型

电商产品筛选

排行榜

Redis-数据类型-应用场景的更多相关文章

  1. Redis数据类型使用场景及有序集合SortedSet底层实现详解

    Redis常用数据类型有字符串String.字典dict.列表List.集合Set.有序集合SortedSet,本文将简单介绍各数据类型及其使用场景,并重点剖析有序集合SortedSet的实现. Li ...

  2. Redis数据类型应用场景及具体方法总结

    StringsStrings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字.使用Strings类型,你可以完全实现目前 Memcached 的功能,并且效率更 ...

  3. redis数据类型及使用场景

    Redis数据类型  String: Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字. 常用命令:  set,get,decr,incr,mge ...

  4. redis 数据类型详解 以及 redis适用场景场合

    1.  MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的 ...

  5. redis的使用场景和基本数据类型

    一:redis使用的场景 redis是一个高性能的NoSQL数据库,特点是高性能,持久存储,适应高并发的应用场景. 下面看看它的使用场景1.取最新N个数据的操作比如取网站的最新文章,通过下面方式,我们 ...

  6. redis 数据类型详解 以及 redis适用场景场合(滴滴)

    滴滴的面试官问了个问题关于redis的: 我现在想服务器每分钟接收一个用户的请求小于60个,如何处理: 答:使用Redis 缓存服务器,可以设置key=用户ID value不停地加一到了60就停止,然 ...

  7. Redis五种数据类型应用场景

    目录 1.1 回顾 2.1 应用场景 2.1.1 String 2.1.2 Hash 2.1.3 List 2.1.4 Zet 2.1.5 zset 3.1 小结 1.1 回顾 Redis的五种数据类 ...

  8. redis数据类型及应用场景

    0.key的通用操作 KEYS * keys a keys a* 查看已存在所有键的名字 ****TYPE 返回键所存储值的类型 ****EXPIRE\ PEXPIRE 以秒\毫秒设定生存时间 *** ...

  9. Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势

    一.Redis数据类型 1.string string是Redis的最基本数据类型,一个key对应一个value,每个value最大可存储512M.string一半用来存图片或者序列化的数据. 2.h ...

  10. Redis的使用场景 by 杨卫华

    转载自新浪微博架构师杨卫华的博客 http://timyang.net/tag/redis/,省略了部分内容 按:杨卫华在2010年就已经测试了Redis的性能,并给出了初步的结论:“Redis性能惊 ...

随机推荐

  1. JUC学习笔记(二)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html 1.Lock接口 1.1.Synchronized 1.1.1.Synchronized关 ...

  2. 网安日记④之搭建域环境(domain)并且配置域

    搭建域环境(domain)并且配置域 什么是域 域就是将多台计算机在逻辑上组织到一起,进行集中管理,也就是创建在域控制器上的组,将组的账户信息保存在活动目录中.域组可以用来控制域内任何一台计算机资源的 ...

  3. SpringCloud升级之路2020.0.x版-13.UnderTow 核心配置

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford Undertow ...

  4. Nginx整数溢出漏洞 Writeup

    Nginx整数溢出漏洞 CVE-2017-7529 题目URL:http://www.whalwl.site:8040/ 漏洞描述 在 Nginx 的 range filter 中存在整数溢出漏洞,可 ...

  5. [源码解析] 机器学习参数服务器Paracel (3)------数据处理

    [源码解析] 机器学习参数服务器Paracel (3)------数据处理 目录 [源码解析] 机器学习参数服务器Paracel (3)------数据处理 0x00 摘要 0x01 切分需要 1.1 ...

  6. pikachu RCE远程系统命令执行

    远程系统命令执行 一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口比如我们常见的路由器.防火墙.入侵检测等设备的web管理界面上一般会给用户提供一个ping操作的web界 ...

  7. VsCode安装使用教程和插件安装方法

    许多渗透方式都python写脚本,比较方便,写一下vscode和插件的安装办法,虽然不是很复杂,但是写一下做一下笔记: Visual Studio Code (简称 VS Code / VSC) 是一 ...

  8. Windows内核基础知识-1-段寄存器

    Windows内核基础知识-1-段寄存器 学过汇编的应该都知道段寄存器,在Windows里段寄存器有很多,之前可能只接触了ds数据段,cs 代码段这种,今天这个博客就介绍Windows一些比较常用的段 ...

  9. Windows下安装RocketMQ

    目录 前言 环境 具体操作 下载 环境变量配置 启动 关闭 生产.消费实例 RocketMQ Console 前言 项目中用到了延迟消息队列,记录下一win10下rocketmq的安装 环境 win1 ...

  10. pip的问题 Can't connect to HTTPS URL because the SSL module is not available

    pip is configured with locations that require TLS/SSL, however the ssl module in Python is not avail ...