2026/8/13 12:50:38

【Redis】零基础入门篇

【Redis】零基础入门篇 前言Redis的安装是在Linux如你没学过Linux也可以参考我的文章 Linux入门命令大全Redis博客导航Redis入门篇Redis实战篇Redis高级篇Redis原理篇宝剑锋从磨砺出梅花香自苦寒来希望该博客对你有所帮助文章目录前言初始Redis认识NoSQL介绍Redis安装服务启动Redis客户端图形化桌面客户端数据类型常用命令key的层级格式字符串操作命令哈希操作命令列表操作命令集合操作命令有序集合操作命令通用命令客户端服务端在Java中操作RedisJedisSpring Data Redis介绍使用方式序列化自定义RedisTemplateStringRedisTemplate(推荐)String类型操作List类型操作Set类型操作Hash类型操作ZSet类型操作通用操作持久化机制RDBAOF工作原理刷盘策略文件膨胀 重写初始Redis认识NoSQL数据结构维度SQL 数据库NoSQL 数据库数据类型仅支持结构化数据。有固定格式、固定字段、固定类型的数据支持非结构化 / 半结构化 / 结构化全类型。无固定格式、无固定字段数据模型固定表结构行 列灵活模型文档、键值、列族、图结构要求必须先定义表结构不可随意修改。要加字段必须修改表结构麻烦。不用提前定义结构直接存数据。无固定结构每条数据字段可不一样数据关联强关联JOIN 多表联查弱关联 / 无关联不推荐 JOIN事务强事务ACID弱事务 / 最终一致性BASE典型场景银行、订单、财务、ERP社交、日志、大数据、内容平台数据关联SQL 关系型数据库表与表之间用主键、外键物理绑定关联关系数据库底层强制约束完整性。例用户表 (user)、订单表 (order)订单表存 user_id 作为外键指向用户表主键 id删除用户时可级联删除订单保证关联数据一致性。NoSQL原生弱支持无外键仅手动 ID 引用数据尽量内嵌聚合存储减少跨文档、跨集合关联查询弱化表间绑定。示例一条用户文档直接内嵌该用户所有订单读取一次文档就能拿到全部关联信息无 JOIN 开销。{_id:1,username:张三,orders:[{orderId:101,price:99},{orderId:102,price:199}]}SQL查询语言SQL统一标准 SQL 语言。结构化查询语言是关系型数据库专属标准查询语言有统一国际标准语法ANSI SQL所有关系库MySQL、Oracle、SQL Server、PostgreSQL基础语法高度兼容。NoSQL无统一语言各库语法不同不同类型 NoSQL 数据库拥有独立查询语法。SQL 用统一标准化语言解决复杂数据查询与关联统计NoSQL 放弃统一 SQL 标准用轻量化专属语法换取高并发读写性能。事务SQL原生强事务ACID 四大特性NoSQL整体偏向 BASE放弃实时强一致换取高并发、高可用、水平扩容能力。BASEBasically Available基本可用、Soft State柔性状态、Eventually Consistent最终一致性基本可用 Basically Available系统哪怕一部分节点故障、流量暴打不会直接整体崩溃宕机依然能对外提供核心服务允许非核心功能降级。正面例子电商大促某台服务器崩了集群其他节点顶上首页商品正常浏览只是暂时关闭评论、推荐等次要功能下单支付核心流程保留。和 ACID 区别关系型数据库为了强一致节点故障可能直接锁住、拒绝访问NoSQL 优先保 “能访问”牺牲小部分完整功能。核心可用性优先级 完美完整性。柔性状态 Soft State软状态数据允许中间不一致临时状态不需要任意时刻所有节点数据完全同步一致。关系型 SQL硬状态只要事务没提交别人读不到未提交数据提交瞬间全库统一不存在 “一半更新一半没更新”。NoSQL 软状态举例你在分布式集群修改用户昵称A 节点已经更新B、C 节点还没同步短时间内不同服务器查到名字不一样这个短暂不同步就是柔性状态。核心允许数据存在短暂不一致中间态不用强制瞬时全局统一。最终一致性 Eventually Consistent柔性状态只是临时的经过一小段同步延迟毫秒 / 秒级所有节点数据会自动同步一段时间后全网数据完全一致只是不保证修改后立刻一致。举例朋友圈点赞你刚点完自己页面立刻显示点赞数 1好友刷新页面几秒后才看到你的点赞几秒后所有人查看点赞数字完全统一。中间几秒不同步完全可接受不需要点赞一瞬间全球所有服务器同步完成。核心不追求实时一致只保证一定时间后收敛一致。介绍Redis 全称是 Remote Dictionary Server远程字典服务器你可以把它理解成一个 “内存数据库” —— 所有数据都存在内存里读写速度飞快比传统的 MySQL 快几十到上百倍同时它也支持把数据持久化到硬盘不用担心重启后数据丢失。Redis 是一款把数据存在内存中的键值对数据库MySQL是一款把数据存在磁盘中的二维表数据库打个比方传统数据库比如 MySQL像家里的衣柜找衣服需要打开柜门、翻抽屉速度慢但能存很多东西Redis 像你口袋里的钱包钱数据就在手边拿取瞬间完成虽然容量小但速度极快。Redis 的核心特点速度快基于内存操作IO 多路复用每秒能处理几十万次读写请求数据类型丰富 键值型value 支持不同数据结构还能存 字符串、列表、哈希、集合等满足多种场景数据持久化内存数据可以存到硬盘重启后能恢复支持分布式可以多台服务器一起用应对高并发实际应用场景缓存最核心用途比如你打开某购物 App首页的商品列表、你的个人信息这些数据如果每次都从 MySQL 查速度慢还耗服务器资源。Redis 会先把这些 “常用数据” 存到内存里用户再访问时直接从 Redis 拿瞬间加载App 就不会卡顿。计数器 / 排行榜比如视频的播放量、文章的点赞数、电商的销量排行榜Redis 能快速实现 “实时计数” 和 “排序”比如每点击一次播放Redis 里的数字就 1毫秒级完成。秒杀 / 限流比如电商的 “618 秒杀”瞬间有几十万人抢商品Redis 能精准控制并发请求防止服务器被冲垮还能保证 “一人一单” 不超卖。消息队列比如 App 的推送通知、订单支付后的短信提醒Redis 可以临时存这些 “待处理的消息”确保不丢失、按顺序处理。总结即在某个特定时间点一般较短有大量用户去访问数据访问量大Redis安装大多数企业都是基于Linux服务器来部署项目而且Redis官方也没有提供Windows版本的安装包Windows版redis是微软搞出来的。因此课程中我们会基于Linux系统来安装Redis此处选择的Linux版本为CentOS 7.如你没学过Linux也可以参考我的文章 Linux入门命令大全Redis的官方网站地址https://redis.io/yum EPEL 源 CentOS7 安装Redis最高就到 3.2.12 老旧版本建议源码安装。Redis是基于C语言编写的因此首先需要安装Redis所需要的gcc依赖yuminstall-ygcc tcl放到了/usr/local/src 目录cd/usr/local/src解压tar-xzfredis-6.2.6.tar.gz进入redis目录cdredis-6.2.6运行编译命令makemakeinstall如果没有出错应该就安装成功了。默认的安装路径是在 /usr/local/bin 目录下该目录以及默认配置到环境变量因此可以在任意目录下运行这些命令。其中redis-cli是redis提供的命令行客户端redis-server是redis的服务端启动脚本redis-sentinel是redis的哨兵启动脚本服务启动在当前文件夹cmd中输入指令服务端启动命令redis-server.exe redis.windows.confRedis服务默认端口号为6379通过快捷键CtrlC 即可停止服务启动客户端点击redis-cli.exe输入auth root123456退出客户端exit连接其他地方的redisredis-cli.exe -h localhost(换) -p 6379(换) -a root123456(密码)输入ping回复pong即连接成功启动图形化界面前要先启动服务端默认启动这种启动属于前台启动会阻塞整个会话窗口窗口关闭或者按下 CTRL C 则Redis停止不推荐使用。redis-server指定配置启动如果要让Redis以后台方式启动则必须修改Redis配置文件。就在我们之前解压的redis安装包下/usr/local/src/redis-6.2.6名字叫redis.conf我们先将这个配置文件备份一份cpredis.conf redis.conf.bck然后修改redis.conf文件中的一些配置vimredis.conf#建议在命令模式按 /进入搜索模式比如 /daemonize再回车会好找一点n下一个N上一个# 监听的地址默认是127.0.0.1会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问生产环境不要设置为0.0.0.0bind0.0.0.0# 守护进程修改为yes后即可后台运行daemonizeyes# 密码设置后访问Redis必须输入密码requirepass1234Redis的其它常见配置# 监听的端口port6379# 工作目录默认是当前目录也就是运行redis-server时的命令日志、持久化等文件会保存在这个目录dir.# 数据库数量设置为1代表只使用1个库默认有16个库编号0~15databases1# 设置redis能够使用的最大内存maxmemory 512mb# 日志文件默认为空不记录日志可以指定日志文件名logfileredis.log启动Redis# 进入redis安装目录cd/usr/local/src/redis-6.2.6# 启动redis-server redis.conf停止服务# 利用redis-cli来执行 shutdown 命令即可停止 Redis 服务# 因为之前配置了密码因此需要通过 -u 来指定密码redis-cli-u1234shutdown开机自启首先新建一个系统服务文件vim/etc/systemd/system/redis.service内容如下[Unit]Descriptionredis-serverAfternetwork.target[Service]TypeforkingExecStart/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.confPrivateTmptrue[Install]WantedBymulti-user.target然后重载系统服务systemctl daemon-reload现在我们可以用下面这组命令来操作redis了# 启动systemctl start redis# 停止systemctl stop redis# 重启systemctl restart redis# 查看状态systemctl status redis执行下面的命令可以让redis开机自启systemctlenableredis登录客户端命令redis-cliRedis客户端安装完成Redis我们就可以操作Redis实现数据的CRUD了这需要用到Redis客户端。Redis安装完成后就自带了命令行客户端redis-cli使用方式如下redis-cli[options][commonds]其中常见的 options 有-h 127.0.0.1指定要连接的redis节点的IP地址默认是127.0.0.1-p 6379指定要连接的redis节点的端口默认是6379-a 123321指定 redis 的访问密码其中的 commonds 就是Redis的操作命令例如ping与redis服务端做心跳测试服务端正常会返回 pong图形化桌面客户端如果连接不上就关闭防火墙或者开放6379端口systemctl stop firewalld systemctl disable firewalldRedis默认有16个仓库编号从0至15。通过配置文件可以设置仓库数量但是不超过16并且不能自定义仓库名称。如果是基于redis-cli连接Redis服务可以通过select命令来选择数据库# 选择 0号库select0数据类型Redis 存储的是 key-value 结构的数据其中 key 一般是字符串类型value 有5种常用的数据类型字符串(string)普通字符串Redis中最简单的数据类型哈希(hash)也叫散列类似于Java中的 HashMap 结构列表(Iist)按照插入顺序排序可以有重复元素类似于Java中的LinkedList集合(set)无序集合没有重复元素类似于Java中的HashSet有序集合(sorted set/zset)集合中每个元素关联一个分数(score)根据分数升序排序没有重复元素常用命令key的层级格式Redis没有类似MySQL中的Table的概念我们该如何区分不同类型的 key 呢例如需要存储用户、商品信息到redis有一个用户 id 是1有一个商品 id 恰好也是1Redis 的 key 允许有多个单词形成层级结构多个单词之间用冒号 **: **隔开格式如下项目名 : 业务名 : 类型 : id这个格式并非固定也可以根据自己的需求来删除或添加词条。例如我们的项目名称叫 shop有 user 和 product 两种不同类型的数据我们可以这样定义keyuser相关的keyshop:user:1product相关的keyshop:product:1如果Value是一个Java对象例如一个User对象则可以将对象序列化为SON字符串后存储KEYVALUEshop:user:1{“id”:1,“name”:“Jack”,“age”:21}shop:product:1{“id”:1,“name”:“小米 11”,“price”:4999}例如set shop:user:1 ‘{“id”:1,“name”:“Jack”,“age”:21}’json格式、单词带空格、含特殊符号 要记得加单引号字符串操作命令其value是字符串不过根据字符串的格式不同又可以分为 3 类string普通字符串int整数类型可以做自增、自减操作float浮点类型可以做自增、自减操作不管是哪种格式底层都是字节数组形式存储只不过是编码方式不同。字符串类型的最大空间不能超过512M。常用命令set key value设置指定key的值get key获取指定key的值mset k1 v1 k2 v2 …批量添加多个String类型的键值对mget k1 k2 …根据多个key获取多个String类型的valuesetex key seconds value设置指定key的值并将key的过期时间设为seconds秒setnx key value只有在key不存在时设置key的值incr key将key中存储的整型数字值加一incrby key increment将key所储存的整型值加上给定的增量值(increment)incrbyfloat key increment让一个浮点类型的数字自增并指定步长decr key将key中储存的数字值减一decrby key decrementkey所储存的值减去给定的减量值(decrement)哈希操作命令hash是一个string类型的 field 和 value 的映射表hash特别适合用于存储对象。String 结构是将对象序列化为 JSON 字符串后存储当需要修改对象单个字段时很不方便。Hash结构可以将对象中的每个字段独立存储可以针对单个字段做CRUD。常用命令hset key field value将哈希表key中的字段field的值设为valuehget key field获取存储在哈希表中指定字段的值hmset key field1 valuel field2 value2同时将多个field-value(域-值)对设置到哈希表key中hmget key field1 field2获取所有给定字段的值hdel key field删除存储在哈希表中的指定字段hkeys key获取哈希表中所有字段hvals key获取哈希表中所有值hgetall key获取一个key中所有的域值hincrby key field increment让一个hash类型key的字段值自增并指定步长hsetnx key field添加一个hash类型的key的field值前提是这个field不存在否则不执行列表操作命令Redis中的 List 类型与Java中的 LinkedList 类似可以看做是一个双向链表结构既可以支持正向检索和也可以支持反向检索。特征也与 LinkedList 类似有序、元素可以重复、插入和删除快、查询速度一般Redis列表是简单的字符串列表按照插入顺序排序常用命令lpush key value1 [value2]将一个或多个值插入到列表头部rpush key value1 [value2]将一个或多个值插入到列表尾部lrange key start stop获取列表指定范围内的元素start为起始索引一般从0开始想拿到所有元素stop就写-1lpop key移出并获取列表的第一个元素rpop key移除并获取列表最后一个元素llen key获取列表长度rpoplpush source dest移除列表的最后一个元素并将该元素添加到另一个列表并返回brpoplpush source dest timeout从列表中弹出一个值将弹出的元素插入到目标列表中并返回它如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。blpop key1 [key2 …] timeout从队列头部取出元素元素取出后直接从原队列删除brpop key1 [key2 …] timeout从队列尾部取出元素元素取出后直接从原队列删除集合操作命令Redis的 Set 结构与Java中的 HashSet 类似可以看做是一个 value 为 null 的 HashMap。因为也是一个hash表因此具备与HashSet类似的特征无序、元素不可重复、查找快、支持交集、并集、差集等功能常用命令sadd key member1 [member2]向集合添加一个或多个成员smembers key返回集合中的所有成员sismember key member判断一个元素是否存在于set中scard key获取集合的成员数sinter key1 [key2]返回给定所有集合的交集sunion key1 [key2]返回所有给定集合的并集sdiff key1 [key2]返回所有给定集合的差集srem key member1 [member2]删除集合中一个或多个成员有序集合操作命令Redis的 SortedSet 是一个可排序的 set 集合与Java中的 TreeSet 有些类似但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性可以基于 score 属性对元素排序底层的实现是一个跳表SkipList hash表。SortedSet 具备下列特性可排序、元素不重复、查询快因为SortedSet的可排序特性经常被用来实现排行榜这样的功能。常用命令zadd key score1 member1 [score2 member2]向有序集合添加一个或多个成员如果已存在则更新其 score 值zrange key start stop [withscores]按照score排序后返回有序集合中指定 排名范围内的成员分数从小到大zrangebyscore key min max按照score排序后获取指定 score 范围内的元素注意所有的排名默认都是升序如果要降序则在命令的 z 后面添加 rev 即可zincrby key increment member有序集合中对指定成员的分数加上增量 incrementzrem key member [member …]移除有序集合中的一个或多个成员zcard key计算集合中元素的数量zscore key member获取sorted set中的指定元素的score值zrank key member获取sorted set中的指定元素的排名zcount key min max统计score值在给定范围内的所有元素的数量zdiff、zinter、zunion求差集、交集、并集通用命令客户端Redis的通用客户端命令是不分数据类型的都可以使用的命令keys *获取全部的keykeys pattern查找所有符合给定模式(pattern)的key例如 *name匹配 lastname 等在生产环境中不建议用这个命令数据量达到一定规模后搜索会变慢又因为redis是单线程会阻塞redis服务exists key检查给定key是否存在type key返回key所储存的值的类型del key该命令用于在key存在是删除keyexpire key timeout设置指定key的超时时间ttl key查看key的剩余生存时间(time to live)。正值为过期时间、-1为永久不过期、-2为不存在或已过期persist key移除key的生存时间转换成一个持久的key服务端Redis的通用服务端命令是用来查看redis服务器相关信息的dbsize获取当前数据库中key的数量select db number切换到指定的数据库数据库索引号index用数字值指定以0作为起始索引值flushdb清空当前数据库的所有的keyflushall清空所有数据库的所有的keyinfo获取redis服务器的各种信息及统计数据monitor实时打印出redis服务器接收到的命令调试用在Java中操作RedisJedisJedis 连接池Spring Data Redis介绍提供了对不同Redis客户端的整合Lettuce 和 Jedis提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化支持基于Redis的DKCollection实现使用方式操作步骤创建SpringBoot工程勾选起步依赖配置Redis的连接信息在单元测试中直接注入RedisTemplate对象通过RedisTemplate对象操作Redisspringboot版本别用这么高的版本引入依赖配置文件//在application.yml文件spring:data:redis:host:192.168.130.88port:6379database:0password:1234序列化如果你用 Java 程序往 Redis 里存数据比如用 RedisTemplate但没指定序列化方式Java 会默认用 JdkSerializationRedisSerializer把数据序列化成二进制格式。Redis 里实际存的不是明文 “name”而是上面这串序列化后的字节用 Redis 客户端redis-cli查看时就会显示 \xac\xed\x00\x05t\x00\x04name 这种转义字符可读性差内存占用大。修改序列化方式自定义配置类自定义RedisTemplatevalue 用 JSON实际并不用因为value有可能存入Java对象取的时候也可以反序列化成Java对象经过强转因为存储了对象类的字节码ConfigurationpublicclassRedisConfig{BeanpublicRedisTemplateObject,ObjectredisTemplate(RedisConnectionFactoryredisConnectionFactory){//创建TemplateRedisTemplateObject,ObjecttemplatenewRedisTemplate();//设置连接工厂template.setConnectionFactory(redisConnectionFactory);//指定序列化方式template.setKeySerializer(newStringRedisSerializer());template.setHashKeySerializer(newStringRedisSerializer());returntemplate;}}为了在反序列化时知道对象的类型JSON序列化器会将类的class类型写入json结果中存入Redis会带来额外的内存开销。为了节省内存空间我们并不会使用JSON序列化器来处理value而是统一使用String序列化器要求只能存储String类型的key和value。当需要存储Java对象时手动完成对象的序列化和反序列化。StringRedisTemplate(推荐)Spring默认提供了一个StringRedisTemplate类它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate的过程。String类型操作List类型操作Set类型操作没有展示全部的命令Hash类型操作ZSet类型操作通用操作持久化机制RDBRDB 就是 Redis 把当前内存中的所有数据以 “快照” 的形式相当于给内存数据拍一张 “照片”一次性保存到硬盘上的二进制文件默认文件名是 dump.rdb。save由Redis主进程来执行RDB会阻塞所有命令会暂停所有客户端请求bgsave开启子进程执行RDB避免主进程受到影响优点文件体积小二进制格式比下文的 AOF 文件小很多恢复速度快重启 Redis 时加载 RDB 比加载 AOF 快对性能影响小bgsave 用子进程生成文件主进程不阻塞适合备份可以定时生成 RDB 文件方便归档备份。缺点数据丢失风险如果 Redis 崩溃最后一次快照后的所有修改都会丢失比如按默认配置最多丢 15 分钟数据生成快照成本高如果数据量很大比如几十 Gbgsave 创建子进程会消耗大量内存短暂影响性能不适合实时持久化无法做到 “每修改一条数据就保存”实时性差。AOF它通过记录写命令实现持久化能大幅降低数据丢失风险。Redis 会把所有执行过的写命令比如 set、hset、lpush 等读命令 get、hget 不记录以纯文本的格式一行行追加到 AOF 文件中当 Redis 重启时会重新执行 AOF 文件中的所有写命令把数据恢复到内存中。对比RDB 是给 Redis 内存数据拍一张照片保存的是「数据结果」AOF 是给 Redis 的写操作记流水账保存的是「数据产生的过程」。工作原理阶段 1命令追加AppendRedis 执行任意写命令后会先把命令按照「Redis 通信协议」格式拼接成字符串然后追加到内存中的 AOF 缓冲区不是直接写硬盘避免频繁 IO 操作拖慢性能。阶段 2文件写入WriteRedis 会定期把AOF 缓冲区中的命令写入到硬盘的 AOF 文件中注意写入到操作系统的「硬盘缓存」还没真正落盘。阶段 3文件同步Sync通过配置规则让操作系统把「硬盘缓存」中的数据真正刷写到物理硬盘这一步是保证数据不丢的关键刷写到硬盘后即使服务器断电数据也不会丢失。刷盘策略always每执行一条写命令就立即把缓冲区数据刷写到物理硬盘安全最高几乎不丢数据性能差频繁刷盘IO 密集核心金融 / 支付业务零数据丢失要求everysec每1 秒自动刷盘一次把缓冲区累计的命令刷写到物理硬盘安全较高最多丢 1 秒数据性能适中平衡安全和性能绝大多数业务电商、社交、通用系统no把刷盘操作交给操作系统由系统决定何时刷盘通常 30 秒左右安全最低可能丢几秒到几十秒数据性能好Redis 不做刷盘操作性能最优非核心缓存数据丢数据无影响文件膨胀 重写AOF 是追加式文件所有写命令都会往末尾加时间久了会出现一个严重问题AOF 文件越来越大比如反复执行 incr numAOF 会记录每一次 incr 命令而不是最终的 num 值。比如你执行了 1000 次 incr num 让 num1000AOF 会记录 1000 条 incr num 命令文件会存 1000 行但实际上恢复数据只需要 1 条 set num 1000 就够了这就造成了文件膨胀。AOF 重写就是 Redis 会重新生成一个新的 AOF 文件新文件中只保留「恢复当前数据所需的最少命令」替换掉原来臃肿的旧 AOF 文件从而实现文件瘦身。手动重写在 redis-cli 中执行命令 bgrewriteaofRedis 会创建子进程执行重写自动触发配置文件规则在 Redis 配置文件中通过两个参数配合满足条件后自动执行 bgrewriteaof#自动重写的最小AOF文件大小文件小于这个值即使满足百分比也不重写auto-aof-rewrite-min-size 64mb#自动重写的百分比当前AOF文件大小 / 最后一次重写后的AOF文件大小 ≥ 该值触发重写auto-aof-rewrite-percentage 100