Redis - 介绍与使用场景
简介
Redis 的全称是 Remote Dictionary Server,是一个使用 C 语言编写的、开源的(BSD 许可)高性能非关系型(NoSQL)的键值对数据库。
Redis 的数据是存储在内存中的,所以读写速度非常快,被广泛应用于缓存方向,当然也有持久化数据库的用法。
优缺点
优点
- 读写性能优异, Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s
- 数据类型丰富,有 String、List、Hash、Set、SortedSet 等
- 单线程原子性,Redis 所有的操作都是原子性的,也支持多个操作合并后的原子执行
- 丰富的特性,Redis 支持发布订阅、通知、key 过期等功能
- 支持持久化,Redis 支持 RDB、AOF 等持久化方式
- 高可用性,Redis 支持主从复制、哨兵模式、Cluster 等高可用方式
缺点
- 数据库容量受物理内存的限制,不能用作海量数据的读写
- Redis 难以支持在线扩容,修改配置文件之后重启 Redis,恢复磁盘上的数据耗费时间较久
使用场景
数据缓存
Redis 是高性能的内存数据库,因此,缓存是 Redis 最常用的场景。Redis 作为缓存使用的时候,一般是采用先更新数据库,再删除缓存的 Cache Aside Pattern 策略。
整体的逻辑是:业务从 Redis 中读取数据,如果 Redis 中访问不到数据,然后读取数据库中的数据,将数据库中的数据缓存到 Redis 中;业务更新数据,直接修改数据库中的数据,然后将 Redis 中的缓存删除。
这种方案需要注意的就是:避免缓存击穿,数据的实时性相对较低。
限时业务
Redis 支持给 key 设置过期时间,客户端无法访问到过期的 key,利用这一特性可以运用在限时的优惠活动、手机验证码等业务场景。
计数器
Redis 的 INCRBY 命令可以实现原子性的递增,可以直接作为计数器存储和递增。尤其是,该命令在键不存在时会直接初始化值再执行 INCRBY 命令,执行成功后会直接返回计算增量之后的数值。
高并发的秒杀活动、分布式序列号的生成、限制手机发送短信次数、接口限制访问次数等需要计数的功能,都涉及到计数器的概念,尤其是分布式系统会涉及到分布式计数器。
分布式锁
先使用 SETNX 命令来争抢锁,结果返回 1 表示设置成功,抢到之后再用 EXPIRE 命令给锁加一个过期时间防止忘记释放锁。
从 Redis 的 2.6.12 版本开始,可以通过 SET 命令的复杂参数,将 SETNX 命令和 EXPIRE 命令合并成一条命令来使用:
EX second: 设置键的过期时间为 second 秒,使用EX选项效果等同于SETEX命令。PX millisecond: 设置键的过期时间为 millisecond 毫秒,使用PX选项效果等同于PSETEX命令。NX: 只在键不存在时,才对键进行设置操作,使用NX选项效果等同于SETNX命令。XX: 只在键已经存在时,才对键进行设置操作。
同样的,使用 SET 命令操作成功之后会返回 OK,这样才表示抢到了锁。
为了避免分布式锁被误删,加锁时可以设置线程 ID 作为 value 值,删除时需要线程的线程 ID 和 Redis 存储的值一致才能够删除分布式锁,否则只能等待锁自动过期,整个删除过程使用事务的方式保证原子性。
排行榜功能
通过 Redis 的 SortedSet 可以实现排行榜功能。
比如说需要展示点赞排行榜,可以将用户 ID 作为 SortedSet 的 value 值,将用户的点赞数作为 SortedSet 的 score 值,SortedSet 提供的 ZRANGEBYSCORE 命令可以快速返回已排序的点赞排行榜。
延时队列
延时队列其实就是一个带有延迟功能的消息队列,Redis 可以通过 SortedSet 实现延时队列。
具体的实现如下:
- 将消息内容序列化成一个字符串作为 SortedSet 的 value 值,这个消息的到期处理时间作为 score,生产者调用
ZADD命令生产消息,消费者可以使用ZRANGEBYSCORE命令获取一段时间之前的数据轮询处理; - 通常使用多个线程轮询 SortedSet 获取到期的任务进行处理,多个线程是为了保障可用性,万一挂了一个线程还有其他线程可以继续处理;
- 因为有多个线程,所以需要考虑并发争抢任务,确保任务不能被多次执行,Redis 的
ZREM命令是多线程争抢任务的关键,ZREM命令会返回被成功移除的成员数量,可以通过ZREM命令来决定任务的唯一属主; - 同时也要注意一定要进行异常捕获,避免因为个别任务处理问题导致循环异常退出,同一个任务可能会被多个进程取到之后再使用
ZREM命令进行争抢,那些没抢到的进程都是白取了一次任务,这是浪费; - 通常可以使用 Lua 脚本的方式,将
ZRANGEBYSCORE命令和ZREM命令一同挪到服务器端进行原子化操作,这样多个进程之间争抢任务时就不会出现这种浪费了。
异步队列
第一种方案 是使用 List 结构作为异步队列,RPUSH 命令生产消息,LPOP 命令消费消息。当使用 LPOP 命令没有得到消息的时候,需要适当 sleep 一会再重试,在这里 sleep 会导致消息的处理延迟增加。
如果不做 sleep 重试,改进的 第二种方案 是,使用 LPOP 命令的阻塞版本 BLPOP 命令,在 List 队列中没有消息的时候,它会阻塞直到消息到来,一旦数据到来,则立刻醒过来,消息的延迟几乎为零。但是如果线程一直阻塞,Redis 的客户端连接就成了闲置连接,闲置过久,服务器一般会主动断开连接,减少闲置资源占用。这个时候 BLPOP 命令会抛出异常来,代码中需要处理这样的异常。
除了 List 队列之外,第三种方案 是使用 Pub/Sub 订阅者模式实现一对多的消息队列。但是 Redis 的发布订阅功能是无状态的,对于发布者来说,无法知道发布的消息是否被订阅者接收到,在消费者下线的情况下,生产的消息会丢失。
Redis - 介绍与使用场景的更多相关文章
- 【Redis缓存机制】1.Redis介绍和使用场景
(1)持久化数据库的缺点平常我们使用的关系型数据库有Mysql.Oracle以及SqlServer等,在开发的过程中,数据通常都是通过Web提供的数据库驱动来链接数据库进行增删改查. 那么,我们日常使 ...
- 1.Redis介绍和使用场景
(1)持久化数据库的缺点 平常我们使用的关系型数据库有Mysql.Oracle以及SqlServer等,在开发的过程中,数据通常都是通过Web提供的数据库驱动来链接数据库进行增删改查. 那么,我们日常 ...
- Redis常用数据类型介绍、使用场景及其操作命令
Redis常用数据类型介绍.使用场景及其操作命令 本文章同时也在cpper.info发布. Redis目前支持5种数据类型,分别是: 1.String(字符串) 2.List(列表) 3.Hash(字 ...
- Redis学习笔记(4)——Redis五大数据结构介绍以及应用场景
出处:https://www.jianshu.com/p/f09480c05e42 Redis是典型的Key-Value类型数据库,Key为字符类型,Value的类型常用的为五种类型:String.H ...
- Redis介绍及常用命令
一 Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...
- key-list类型内存数据引擎介绍及使用场景
“互联网数据目前基本使用两种方式来存储,关系数据库或者key value.但是这些互联网业务本身并不属于这两种数据类型,比如用户在社会化平台中的关系,它是一个list,如果要用关系数据库存储就需要转换 ...
- redis 介绍和常用命令
redis 介绍和常用命令 redis简介 Redis 是一款开源的,基于 BSD 许可的,高级键值 (key-value) 缓存 (cache) 和存储 (store) 系统.由于 Redis 的键 ...
- Redis介绍及Jedis测试
1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes ...
- Redis简介及应用场景
一丶Redis介绍 Redis是一个开源的 key—value型 单线程 数据库,支持string.list.set.zset和hash类型数据. 默认端口:6379 默认数据库数量:16 二.优点: ...
- Redis介绍及Jedis基础操作
1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes ...
随机推荐
- Windows7下驱动开发与调试体系构建——3.调试体系概述
目录/参考资料:https://www.cnblogs.com/railgunRG/p/14412321.html 调试体系概述 0.什么是自建调试体系? 就是复写windows的调试api,使得调试 ...
- docker容器化业务
1.环境准备: 设备 IP地址 作用 系统版本 mysql-master 192.168.100.213 Nginx-Web服务器 Ubuntu2004 mysql-slave 192.168.100 ...
- SpringCloud(九) - Nginx
1.安装Nginx 1.1 解压上传安装包 解压# nginx-1.16.1.tar.gz # nginx需要一些环境(全部执行,不存在的会执行,存在的会跳过) yum install -y wget ...
- 洛谷 P4135 作诗 题解
题面. 之前做过一道很类似的题目 洛谷P4168蒲公英 ,然后看到这题很快就想到了解法,做完这题可以对比一下,真的很像. 题目要求区间内出现次数为正偶数的数字的数量. 数据范围1e5,可以分块. 我们 ...
- Ajax(下)
跨域 跨域的概念:非同源请求,均为跨域.如果两个页面拥有相同的协议(protocol),端口(port)和主机(host),那么这两个页面就属于同一个源(origin). 例如:主机:http://w ...
- 2022-11-05 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...
- 棋盘覆盖(java实现)
棋盘覆盖 问题描述 在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘 ...
- Containerd 如何配置 Proxy?
前言 在某些 air gap 场景中,往往需要离线或使用代理 (Proxy), 例如: 需要通过 Proxy pull 容器镜像: Docker Hub: docker.io Quay: quay.i ...
- php 程序员进化之路
1.目标明确 2.消除干扰 3.自我激励 鸟哥 --2018年11月17日php年会
- .net随笔——Web开发config替换到正式config appSettings
前言(废话) 查了一些资料,总体来说呢,就是坑,而且顺带吐槽下百度,一个内容被copy那么多遍还排在最前面.同一个内容我点了那么多次,淦. 正题: 实现目的:开发的时候使用system.debug.c ...