title: “redis基础与进阶”
date: 2022-03-28T02:47:49-07:00
draft: true
categories: [“数据库”,]
[TOC]
在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原因是因为那时候Web站点基本**问和并发不高、交互也较少。而在后来,随着访问量的提升,使用关系型数据库的Web站点多多少少都开始在性能上出现了一些瓶颈,而瓶颈的源头一般是在磁盘的I/O上。而随着互联网技术的进一步发展,各种类型的应用层出不穷,这导致在当今云计算、大数据盛行的时代,对性能有了更多的需求,主要体现在以下几个方面:
- 低延迟的读写速度:应用快速地反应能极大地提升用户的满意度
- 支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用PB级别的数据和能应对百万级的流量
- 大规模集群的管理:系统管理员希望分布式应用能更简单的部署和管理
为了克服这一问题,NoSQL应运而生,它同时具备了高性能、可扩展性强、高可用等优点,受到广泛开发人员和仓库管理人员的青睐。
关系型数据库(RMDBS)与非关系型数据库(NoSQL)的对比:
数据库中表与表的数据之间存在某种关联的内在关系,因为这种关系,所以我们称这种数据库为关系型数据库。典型:Mysql/MariaDB、postgreSQL、Oracle、SQLServer、DB2、Access、SQLlite3。特点:
- 全部使用SQL(结构化查询语言)进行数据库操作。
- 都存在主外键关系,表,等等关系特征。
- 大部分都支持各种关系型的数据库的特性:事务、存储过程、触发器、视图、临时表、模式、函数
NOSQL:not only sql,泛指非关系型数据库。泛指那些不使用SQL语句进行数据操作的数据库,所有数据库中只要不使用SQL语句的都是非关系型数据库。典型:Redis、MongoDB、hbase、 Hadoop、elasticsearch、图数据库(Neo4j、GraphDB、SequoiaDB)
Redis(Remote Dictionary Server ,远程字典服务) 是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库,是NoSQL数据库。
redis特性:
- 速度快
- 持久化
- 多种数据结构
- 支持多种编程语言
- 主从复制
- 高可用、分布式
Redis提供的数据类型主要分为5种自有类型和一种自定义类型,这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和顺序集合类型。
讯享网

Redis 的应用场景包括:
缓存系统(“热点”数据:高频读、低频写):缓存用户信息,优惠券过期时间,验证码过期时间、session、token等
计数器:帖子的浏览数,视频播放次数,评论次数、点赞次数等
消息队列,秒杀系统
社交网络:粉丝、共同好友(可能认识的人),兴趣爱好(推荐商品)
排行榜(有序集合)
发布订阅:粉丝关注、消息通知
redis的官方只提供了linux版本的redis,window系统的redis是微软团队根据官方的linux版本高仿的。
官方原版: https://redis.io/
中文官网:http://www.redis.cn
下载地址:https://github.com/tporadowski/redis/releases









使用以下命令启动redis服务端
讯享网

关闭上面这个cmd窗口就关闭redis服务器服务了。

redis作为windows服务启动方式
讯享网
ubuntu下安装:
讯享网
redis 安装成功以后,window下的配置文件保存在软件 安装目录下,如果是mac或者linux,则默认安装/etc/redis/redis.conf
绑定ip:访问白名单,如果需要远程访问,可将此注释,或绑定1个真实ip
端⼝,默认为6379
讯享网
是否以守护进程运行
- 如果以守护进程运行,则不会在命令阻塞,类似于服务
- 如果以守护进程运行,则当前终端被阻塞
- 设置为yes表示守护进程,设置为no表示⾮守护进程
- 推荐设置为yes
RDB持久化的备份策略(RDB备份是默认开启的)
讯享网
RDB持久化的备份文件
RDB持久化数据库数据文件的所在目录
讯享网
日志文件所载目录
进程ID文件
讯享网
数据库,默认有16个,数据名是不能自定义的,只能是0-15之间,当然这个15是数据库数量-1
redis的登录密码,生产阶段打开,开发阶段避免麻烦,一般都是注释的。redis在6.0版本以后新增了ACL访问控制机制,新增了用户管理,这个版本以后才有账号和密码,再次之前只有没有密码没有账号
讯享网
注意:开启了以后,redis-cli终端下使用 来认证登录。

AOF持久化的开启配置项(默认值是no,关闭状态)
AOF持久化的备份文件(AOF的备份数据文件与RDB的备份数据文件保存在同一个目录下,由dir配置项指定)
讯享网
AOF持久化备份策略[时间]
哨兵集群:一主二从三哨兵(3台服务器)
redis是一款基于CS架构的数据库,所以redis有客户端redis-cli,也有服务端redis-server。
其中,客户端可以使用go、java、python等编程语言,也可以终端下使用命令行工具管理redis数据库,甚至可以安装一些别人开发的界面工具,例如:RDM。

redis-cli客户端连接服务器:
讯享网

- SET/SETEX/MSET/MSETNX
- GET/MGET
- GETSET
- INCR/DECR
- DEL
1. 设置键值
set 设置的数据没有额外操作时,是不会过期的。
讯享网
设置键为值为的数据

注意:redis中的所有数据操作,如果设置的键不存在则为添加,如果设置的键已经存在则修改。
设置一个键,当键不存在时才能设置成功,用于一个变量只能被设置一次的情况。
讯享网
一般用于给数据加锁(分布式锁)
2. 设置键值的过期时间
redis中可以对一切的数据进行设置有效期。以秒为单位
讯享网
设置键为值为过期时间为10秒的数据
3. 关于设置保存数据的有效期
setex 添加保存数据到redis,同时设置有效期,格式:
讯享网

4. 设置多个键值
例3:设置键为值为、键为值为、键为值为
讯享网
5. 字符串拼接值
常见于大文件上传
向键为中拼接值
讯享网
6. 根据键获取值
根据键获取值,如果不存在此键则返回
获取键的值
讯享网
根据多个键获取多个值
获取键的值
讯享网
getset:设置key的新值,返回旧值
7. 自增自减
web开发中的电商抢购、秒杀。游戏里面的投票、攻击计数。系统中计算当前在线人数、
讯享网
8. 获取字符串的长度
9. 比特流操作
————————
mykey 00000011
1字节=8比特 1kb = 1024字节 1mb = 1024kb 1gb = 1024mb
1个int8就是一个字节,一个中文:3个字节
讯享网
案例1:
我们知道 'a' 的ASCII码是 97。转换为二进制是:0。offset的学名叫做“偏移” 。二进制中的每一位就是offset值啦,比如在这里 offset 0 等于 ‘0’ ,offset 1等于 '1' ,offset 2 等于 '1',offset 6 等于 '0' ,没错,offset是从左往右计数的,也就是从高位往低位。
我们通过SETBIT 命令将 andy中的 'a' 变成 'b' 应该怎么变呢?
也就是将 0 变成 0 (b的ASCII码是98),这个很简单啦,也就是将'a'中的offset 6从0变成1,将offset 7 从1变成0 。
案例2:签到系统
讯享网
redis中所有的数据都是通过key(键)来进行操作,这里我们学习一下关于任何数据类型都通用的命令。

(1)查找键
参数支持简单的正则表达式
查看所有键
讯享网
例子:
(2)判断键是否存在
如果存在返回,不存在返回
讯享网
判断键是否存在
(3)查看键的的值的数据类型
讯享网
查看键的值类型
(4)删除键以及键对应的值
讯享网
(5)查看键的有效期
(6)设置key的有效期
给已有的数据重新设置有效期,redis中所有的数据都可以通过expire来设置它的有效期。有效期到了,数据就被删除。
讯享网
(7)清空所有key
慎用,一旦执行,则redis所有数据库0~15的全部key都会被清除
(8)key重命名
讯享网
把name重命名为username
select切换数据库
讯享网
操作效果:
队列,列表的子成员类型为string
lpush key value
rpush key value
linsert key after|before 指定元素 value
lindex key index
lrange key start stop
lset key index value
lrem key count value
(1)添加子成员
讯享网
从键为的列表左侧添加一个或多个数据
从键为brother的列表右侧添加一个或多个数据,
讯享网
从key=brother的xiaohong的列表位置左侧添加一个数据,
从key=brother,key=xiaohong的列表位置右侧添加一个数据,
讯享网
注意:当列表如果存在多个成员值一致的情况下,默认只识别第一个。
(2)基于索引获取列表成员
根据指定的索引(下标)获取成员的值,负数下标从右边-1开始,逐个递减
讯享网
获取brother下标为2以及-2的成员
(3)获取列表的切片
闭区间[包括stop]
讯享网
操作:
(4)获取列表的长度
讯享网
获取brother列表的成员个数
(5)按索引设置值
讯享网
修改键为的列表中下标为的元素值为
(6)删除指定成员
移除并获取列表的第一个成员或最后一个成员
讯享网
获取并移除brother中的第一个成员
讯享网
hset key field value
hget key field
hgetall info
hmget key field1 field2 ...
hincrby key field number
专门用于结构化的数据信息。对应的就是map/结构体
结构:
(1)设置指定键的属性/域
设置指定键的单个属性
讯享网
设置键 的属性为
(2)获取指定键的域/属性的值
获取指定键所有的域/属性
讯享网
获取键user的所有域/属性
获取指定键的单个域/属性的值
讯享网
获取键属性的值
获取指定键的多个域/属性的值
讯享网
获取键属性、的值
获取指定键的所有值
讯享网
获取指定键的所有域值对
(3)获取hash的所有域值对
讯享网
(4)删除指定键的域/属性
删除键的属性,当键中的hash数据没有任何属性,则当前键会被redis删除
讯享网
(5)判断指定属性/域是否存在于当前键对应的hash中
判断user:2中是否存在age属性
讯享网
(6)属性值自增自减
给user:2的age属性在原值基础上+/-10,然后在age现有值的基础上-2
讯享网
无序集合,重点就是去重和无序。
(1)添加元素
向键的集合中添加元素、、
讯享网
(2)获取集合的所有的成员
获取键的集合中所有元素
讯享网
(3)获取集合的长度
获取s2集合的长度
讯享网
(4)随机抽取一个或多个元素
抽取出来的成员被删除掉
随机获取s2集合的成员
讯享网
(5)删除指定元素
删除键的集合中元素
讯享网
(6)交集、差集和并集
推荐、(协同过滤,基于用户、基于物品)
讯享网
有序集合(score/value),去重并且根据score权重值来进行排序的。score从小到大排列。
(1)添加成员
设置榜单achievements,设置成绩和用户名作为achievements的成员
讯享网
(2)获取score在指定区间的所有成员
讯享网
(3)获取集合长度
获取users的长度
讯享网
(4)获取指定成员的权重值
获取users中xiaoming的成绩
讯享网
(5)获取指定成员在集合中的排名
排名从0开始计算
获取achievements中xiaohei的分数排名,从大到小
讯享网
(6)获取score在指定区间的所有成员数量
获取achievements从0~60分之间的人数[闭区间]
讯享网
(7)给指定成员增加增加权重值
给achievements中xiaobai增加10分
讯享网
(8)删除成员
从achievements中删除xiaoming的数据
讯享网
(9)删除指定数量的成员
例子:
讯享网
(1)连接redis
通常情况下, 当我们需要做redis操作时, 会创建一个连接, 并基于这个连接进行redis操作, 操作完成后, 释放连接,一般情况下, 这是没问题的, 但当并发量比较高的时候, 频繁的连接创建和释放对性能会有较高的影响。于是, 连接池就发挥作用了。连接池的原理是, 通过预先创建多个连接, 当进行redis操作时, 直接获取已经创建的连接进行操作, 而且操作完成后, 不会释放, 用于后续的其他redis操作。这样就达到了避免频繁的redis连接创建和释放的目的, 从而提高性能。
(2)数据类型操作
讯享网

第1个是最基础也是最常?的就是KV功能,我们可以用Redis来缓存用户信息、会话信息、商品信息等等。下面这段代码就是通过缓存读取逻辑。
什么是分布式锁
❝
分布式锁其实就是,控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共享了某个临界资源,往往需要互斥来防止彼此干扰,以保证一致性。
❞
提到Redis的分布式锁,很多小伙伴马上就会想到+ 命令。即先用来抢锁,如果抢到之后,再用给锁设置一个过期时间,防止锁忘记了释放。
❝
SETNX 是SET IF NOT EXISTS的简写.日常命令格式是SETNX key value,如果 key不存在,则SETNX成功返回1,如果这个key已经存在了,则返回0。
❞
假设某电商网站的某商品做秒杀活动,key可以设置为key_resource_id,value设置任意值,伪代码如下:
方案1
讯享网
但是这个方案中,和两个命令分开了,「不是原子操作」。如果执行完加锁,正要执行设置过期时间时,进程crash或者要重启维护了,那么这个锁就“长生不老”了,「别的线程永远获取不到锁啦」。
方案2:SETNX + value值是(系统时间+过期时间)
为了解决方案一,「发生异常锁得不到释放的场景」,可以把过期时间放到的value值里面。如果加锁失败,再拿出value值校验一下即可。加锁代码如下:
方案3
实际上,我们还可以使用Py的redis模块中的set函数来保证原子性(包含setnx和expire两条指令)代码如下:
讯享网
延时队列可以通过Redis的zset(有序列表)来实现。我们将消息序列化为一个字符串作为zset的值。这个消息的到期时间处理时间作为score,然后用多个线程轮询zset获取到期的任务进行处理,多线程时为了保障可用性,万一挂了一个线程还有其他线程可以继续处理。因为有多个线程,所有需要考虑并发争抢任务,确保任务不能被多次执行。

redis的zrem方法是对多线程争抢任务的关键,它的返回值决定了当前实例有没有抢到任务,因为loop方法可能会被多个线程、多个进程调用, 同一个任务可能会被多个进程线程抢到,通过zrem来决定唯一的属主。同时,一定要对handle_msg进行异常捕获, 避免因为个别任务处理问题导致的循环异常退出。
讯享网
利用 Redis 也能实现订单30分钟自动取消。
用户下单之后,在规定时间内如果不完成付款,订单自动取消,并且释放库存使用技术:Redis键空间通知(过期回调)用户下单之后将订单id作为key,任意值作为值存入redis中,给这条数据设置过期时间,也就是订单超时的时间启用键空间通知
开启过期key监听
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/152814.html