1.初识Redis
1.Redis介绍
1.1认识Redis
Redis,诞生于2009年,全称为Remote Dictionary Server(远程词典服务器),是一款开源的基于内存的键值型NoSQL数据库。它以其卓越的性能和灵活的功能,成为开发者们青睐的解决方案,广泛应用于缓存、数据存储和实时分析等多个场景。
1.2认识NoSQL
NoSQL最常见的解释是“non-relational database”,“Not Only SQL”也被很多人接受。NoSQL仅仅是一个概念,泛指非关系型的数据库。
1.3关系型数据库与非关系型数据库的区别
关系型数据库是以关系模型为基础的数据存储系统,关系模型是由数学家E.F. Codd在1970年提出的。关系型数据库严格遵循ACID原则,具有结构化、规范化、事务化等特点。
非关系型数据库NoSQL是一种基于键值对的数据存储系统,与关系型数据库不同,它不遵循ACID原则,而是采用其他的一致性模型。
1.3.1 数据模型
关系型数据库:采用表格结构,数据以行和列的形式存储。传统关系型数据库是结构化数据,每张表在创建的时候都有严格的约束信息,如字段名、字段数据类型、字段约束等,插入的数据必须遵循这些约束。
非关系型数据库:而关系型数据库则对数据格式没有约束,可以是键值对、文档或图形等多种数据模型,灵活性更高,适应不同数据结构。
1.3.2 数据一致性
- 关系型数据库:通常遵循ACID原则(原子性、一致性、隔离性、持久性),确保事务的可靠性。
- 非关系型数据库:多遵循BASE原则(基本可用、软状态、最终一致性),更注重可用性和性能。
1.3.3 数据查询方式
-
关系型数据库:使用SQL(结构化查询语言)进行数据查询和操作。
SELECT id, name,age FROM tb_user WHERE id = 1
-
非关系型数据库:通常没有标准查询语言,查询方式因数据库类型而异,比如使用JSON查询、Redis、MongoDB的查询语法等。
Redis: get user:1 MongoDB: db.user.find({_id: 1}) elasticsearch: GET http://localhost:9200/users/1
1.3.4 扩展方式
- 关系型数据库:主要通过纵向扩展(Scale Up)提高性能,即增加硬件资源(如CPU、内存)来提升处理能力。这种方式最终会遇到扩展瓶颈。
- 非关系型数据库:通过横向扩展(Scale Out)实现性能提升,即通过添加更多服务器节点来分担负载,适合大规模分布式系统。
1.3.5 事务处理
- 关系型数据库:支持复杂的事务操作,确保数据的一致性和完整性。事务具有ACID属性(原子性、一致性、隔离性和持久性)。
- 非关系型数据库:通常不提供全面的事务支持,更注重性能和高可用性。部分NoSQL数据库支持基本的事务操作,但不如关系型数据库强大
1.3.6 适用场景
- 关系型数据库:适合需要复杂查询和强数据一致性的应用,如金融系统、企业资源计划(ERP)等。
- 非关系型数据库:适合快速变化的数据结构、高并发访问和大数据分析场景,如社交媒体、内容管理系统等。
总结
特性 | 关系型数据库 | 非关系型数据库 |
---|---|---|
数据结构 | 结构化:表格形式(行和列),固定列和数据类型 | 非结构化/半结构化:多种格式(文档、键值对、列族、图形),灵活 |
查询语言 | 使用 SQL(结构化查询语言) | 查询语言不统一,依赖于特定数据库 |
数据一致性 | 遵循 ACID 原则,确保事务的一致性和可靠性 | 多遵循 BASE 原则,允许最终一致性 |
扩展性 | 主要是垂直扩展(增加单台服务器的资源) | 支持水平扩展(增加多台服务器) |
适用场景 | 数据结构固定、强一致性需求等(如金融系统、ERP) | 数据结构不固定、快速变化和高并发场景(如社交媒体、物联网) |
数据完整性 | 通过约束和模式管理,确保数据完整性 | 数据结构灵活,不强制定义模式 |
性能 | 在复杂查询和多表联接时性能下降 | 高并发环境下写入和读取性能较好 |
1.4 Redis有哪些数据结构?
1.4.1 String
- 字符串最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复 杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图 片、音频、视频),但是值最大不能超过512MB。
- 字符串主要有以下几个典型使用场景: 缓存功能 计数 共享Session 限速
String的常用命令:
命令 | 描述 |
---|---|
SET | 添加或者修改一个已经存在的String类型的键值对 |
GET | 根据key获取String类型的value |
MEST | 批量添加多个String类型的键值对 |
MGET | 根据多个key获取多个String类型的value |
INCR | 让一个整形的key自增1 |
INCRBY | 让一个整形的key自增并指定步长值,例如:incrby num 2,让num值自增2 |
INCRBYFLOAT | 让一个浮点类型的数字自增并指定步长值 |
SETNX | 添加一个String类型的键值对,前提是这个key不存在,否则不执行,可以理解为真正的**新** 增 |
SETEX | 添加一个String类型的键值对,并指定有效期 |
1.4.2 Hash类型
- 哈希类型是指键值本身又是一个键值对结构。 Hash类型,也叫散列,其中value是一个无序字典,类似于Java中的HashMap结构
- 哈希主要有以下典型应用场景: 缓存用户信息 、缓存对象。
String结构是将对象序列化为JSON字符串后存储,当我们要修改对象的某个属性值的时候很不方便
KEY | VALUE |
---|---|
blog:user:1 | {“id”:1, “name”: “Jack”, “age”: 21} |
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD
Hash的常用命令有
命令 | 描述 |
---|---|
HSET key field value | 添加或者修改hash类型key的field的值 |
HGET key field | 获取一个hash类型key的field的值 |
HMSET | 批量添加多个hash类型key的field的值 |
HMGET | 批量获取多个hash类型key的field的值 |
HGETALL | 获取一个hash类型的key中的所有的field和value |
HKEYS | 获取一个hash类型的key中的所有的field |
HINCRBY | 让一个hash类型key的字段值自增并指定步长 |
HSETNX | 添加一个hash类型的key的field值,前提是这个field不存在,否则不执行 |
1.4.3 List类型
- Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
- 特征也与LinkedList类似:有序、元素可以重复、插入和删除快、查询速度一般
- 应用场景:朋友圈点赞列表,评论列表等。
List的常见命令有:
命令 | 描述 |
---|---|
LPUSH key element … | 向列表左侧插入一个或多个元素 |
LPOP key | 移除并返回列表左侧的第一个元素,没有则返回nil |
RPUSH key element … | 向列表右侧插入一个或多个元素 |
RPOP key | 移除并返回列表右侧的第一个元素 |
LRANGE key star end | 返回一段角标范围内的所有元素 |
BLPOP和BRPOP | 与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil |
1.4.4 Set
- 集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合 中不允许有重复元素,并且集合中的元素是无序的。
- 使用场景: 标签(tag)、 共同关注等
Set的常见命令有:
命令 | 描述 |
---|---|
SADD key member … | 向set中添加一个或多个元素 |
SREM key member … | 移除set中的指定元素 |
SCARD key | 返回set中元素的个数 |
SISMEMBER key member | 判断一个元素是否存在于set中 |
SMEMBERS | 获取set中的所有元素 |
SINTER key1 key2 … | 求key1与key2的交集 |
SUNION key1 key2 … | 求key1与key2的并集 |
SDIFF key1 key2 … | 求key1与key2的差集 |
1.4.5 SortedSet
- 有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是, 它给每个元素设置一个权重(score)作为排序的依据,底层的实现是一个跳表(SkipList)加 hash表。。
- 有序集合主要应用场景: 用户点赞统计、用户排序
SortedSet的常见命令有:
命令 | 描述 |
---|---|
ZADD key score member | 添加一个或多个元素到sorted set ,如果已经存在则更新其score值 |
ZREM key member | 删除sorted set中的一个指定元素 |
ZSCORE key member | 获取sorted set中的指定元素的score值 |
ZRANK key member | 获取sorted set 中的指定元素的排名 |
ZCARD key | 获取sorted set中的元素个数 |
ZCOUNT key min max | 统计score值在给定范围内的所有元素的个数 |
ZINCRBY key increment member | 让sorted set中的指定元素自增,步长为指定的increment值 |
ZRANGE key min max | 按照score排序后,获取指定排名范围内的元素 |
ZRANGEBYSCORE key min max | 按照score排序后,获取指定score范围内的元素 |
ZDIFF、ZINTER、ZUNION | 求差集、交集、并集 |
注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可,例如:
升序
获取sorted set 中的指定元素的排名:ZRANK key member降序
获取sorted set 中的指定元素的排名:ZREVRANK key memeber
1.4.6 GEO
-
GEO 数据结构用于存储地理位置(经度和纬度)数据,支持地理位置的相关操作。
-
使用场景:查找附近的商家或用户、存储和管理位置信息,如配送点、用户位置信息等。
常用命令
命令 | 描述 |
---|---|
GEOADD key longitude latitude member | 添加地理位置 |
GEOPOS key member | 获取位置 |
GEODIST key member1 member2 [unit] | 获取两点间的距离 |
GEORADIUS key longitude latitude radius [unit] | 范围查询 |
1.4.7 BitMap
- BitMap 是一种位数组,可以用于高效的位操作,适合处理大量的布尔值。
- 使用场景:统计用户活跃度(如每日是否登录)、A/B 测试数据存储和分析。
常用命令
命令 | 描述 |
---|---|
SETBIT key offset value | 设置位 |
GETBIT key offset | 获取位 |
BITCOUNT key [start end] | 统计位数 |
BITOP AND destkey key1 key2 ... | 位与运算 |
1.4.8 HyperLogLog
-
HyperLogLog 是一种用于基数估算的数据结构,能够高效统计唯一元素的数量。
-
使用场景:统计网站的唯一访客数量、数据去重,例如分析大数据集中的唯一值。
常用命令
命令 | 描述 |
---|---|
PFADD key element [element ...] | 添加元素 |
PFCOUNT key [key ...] | 获取基数估算 |
PFMERGE destkey sourcekey [sourcekey ...] | 合并 HyperLogLog |
1.4.9 Stream
Stream 是一种用于处理数据流的数据结构,支持按时间顺序存储和消费数据。
使用场景:实时数据处理,如日志收集、消息队列、社交媒体应用的动态消息流。
常用命令
命令 | 描述 |
---|---|
XADD key ID field1 value1 [field2 value2 ...] | 添加数据 |
XREAD [BLOCK milliseconds] COUNT count STREAMS key ID | 读取数据 |
XRANGE key start end [COUNT count] | 查看流内容 |
XTRIM key MAXLEN count | 删除流 |
1.5 Redis可以应用与那些场景?
1.5.1 缓存系统
- 目的:减少数据库访问频率,降低延迟,提高应用性能。
- 示例:将热点数据(如用户信息、产品列表)存储在Redis中,避免频繁查询关系型数据库。
1.5.2 会话存储
- 目的:快速存取用户会话信息,保持用户登录状态。
- 示例:Web应用中,用户登录后将其会话数据存储在Redis中,以便快速读取和更新。
1.5.3 实时分析
- 目的:高效处理和分析实时数据流。
- 示例:利用Redis的发布/订阅功能,实时统计在线用户数量、点赞数等。
1.5.4 队列系统
- 目的:管理任务队列,实现异步处理。
- 示例:使用Redis的列表数据结构实现任务队列,消费者可以从队列中取出任务进行处理。
1.5.5 排行榜和计数器
- 目的:快速更新和查询排名数据或计数。
- 示例:游戏中的排行榜,利用Redis的有序集合(ZSET)来存储和排序玩家的分数。
1.5.6 实时聊天系统
- 目的:快速发送和接收消息。
- 示例:使用Redis的发布/订阅功能,实时推送聊天消息。
1.5.7 分布式锁
- 目的:控制对共享资源的访问,避免数据冲突。
- 示例:利用Redis的SETNX命令实现分布式锁,确保只有一个实例能够操作某一资源。
1.5.8 数据过期管理
- 目的:自动清理过期数据。
- 示例:缓存一些临时数据(如验证码、短链接),设置过期时间,Redis会自动删除。
1.5.9 地理位置信息
- 目的:存储和查询地理位置信息。
- 示例:使用Redis的GEO命令来处理位置相关的数据,如商家附近的用户查询。
1.5.10 消息队列
- 目的:在微服务架构中实现服务间通信。
- 示例:利用Redis的列表和发布/订阅机制,实现服务之间的异步消息传递。
Redis的应用一般会结合项目去问,以一个电商项目的用户服务为例:
- Token存储:用户登录成功之后,使用Redis存储Token
- 登录失败次数计数:使用Redis计数,登录失败超过一定次数,锁定账号
- 地址缓存:对省市区数据的缓存
- 分布式锁:分布式环境下登录、注册等操作加分布式锁 ……