• [问题求助] 如何用setnx实现一个可重入锁?
    如果用setnx来实现分布式锁比较容易,但是如何用setnx实现一个可重入锁?
  • [问题求助] 如何使用redis来实现乐观锁呢?
    如何使用redis来实现乐观锁呢?
  • [问题求助] 为什么redis不支持回滚?
    为什么redis不支持回滚?如果出现了错误也无法回滚,这是为啥?这么设计有什么好处吗?
  • [问题求助] Redisson的lock和tryLock有什么区别?
    Redisson的lock和tryLock有什么区别?
  • [问题求助] Redis的事务和Lua之间有哪些区别?
    Redis的事务和Lua之间有哪些区别?lua脚本可以保证原子性吗?这个原子性和mysql中的原子性是一样的吗?
  • [问题求助] redis的Pipeline是什么?
    redis的Pipeline是什么?它保证原子性吗?和事务又有什么区别呢?
  • [技术干货] Redis入门教程:从基础到实战的完整指南
    Redis入门教程:从基础到实战的完整指南作为当今最流行的内存数据库,Redis凭借其极致的性能、丰富的数据结构和灵活的部署方式,已成为高并发场景下的标配组件。本文将从安装部署、核心概念、基础命令到实战案例,为开发者提供一站式入门指南。一、环境部署:5分钟快速启动1. Linux系统安装(Ubuntu示例)# 添加官方PPA仓库 sudo add-apt-repository ppa:redislabs/redis sudo apt update # 安装Redis服务器与客户端 sudo apt install redis-server # 启动服务并验证 sudo systemctl start redis-server redis-cli ping # 返回"PONG"即安装成功 2. Docker容器化部署(推荐开发环境)docker run --name my-redis -p 6379:6379 -d redis:latest # 进入容器交互终端 docker exec -it my-redis redis-cli3. 配置文件关键参数# /etc/redis/redis.conf 核心配置 bind 0.0.0.0 # 允许远程连接(生产环境建议限制IP) protected-mode no # 关闭保护模式(需配合密码使用) requirepass yourpassword # 设置认证密码 maxmemory 2gb # 内存限制 maxmemory-policy allkeys-lru # 内存淘汰策略 appendonly yes # 开启AOF持久化二、核心数据结构与操作1. 字符串(String)场景:缓存、计数器、分布式锁# 基本操作 SET username "redis_user" EX 3600 # 设置带过期时间的键 GET username INCR page_views # 原子递增 MSET key1 "val1" key2 "val2" # 批量设置 MGET key1 key2 # 实战案例:短信验证码 SETEX sms:13800138000 300 "1234" # 5分钟有效期 GET sms:138001380002. 哈希(Hash)场景:存储对象属性# 用户信息存储 HSET user:1001 name "Alice" age 28 email "alice@example.com" HGETALL user:1001 HINCRBY user:1001 age 1 # 字段递增 HMGET user:1001 name age # 性能对比:相比String存储JSON,Hash减少序列化开销 3. 列表(List)场景:消息队列、最新消息、排序集合# 微博时间线 LPUSH user:1001:timeline "post1" "post2" "post3" LRANGE user:1001:timeline 0 2 # 获取最新3条 RPOP user:1001:timeline # 消费队列消息 # 阻塞式弹出(实现任务队列) BLPOP task_queue 10 # 等待10秒 4. 集合(Set)场景:标签系统、去重、共同关注# 用户兴趣标签 SADD user:1001:tags "music" "sports" "reading" SMEMBERS user:1001:tags SINTER user:1001:tags user:1002:tags # 交集计算 # 抽奖系统实现 SRANDMEMBER winners 5 # 随机抽取5个中奖者 5. 有序集合(ZSet)场景:排行榜、优先级队列、范围查询# 游戏排行榜 ZADD leaderboard "player1" 1000 "player2" 850 "player3" 1200 ZREVRANGE leaderboard 0 2 WITHSCORES # 显示前3名 ZINCRBY leaderboard "player1" 50 # 增加分数 ZCOUNT leaderboard 900 1100 # 分数段统计 三、高级特性实战1. 持久化机制方案RDB(快照)AOF(日志)触发方式手动/定时自动每条命令追加文件格式二进制压缩文本协议恢复速度快(单文件加载)慢(需重放命令)数据安全性可能丢失最后一次快照后数据最多丢失1秒数据(fsync策略)配置建议:# 混合持久化(Redis 4.0+) aof-use-rdb-preamble yes2. 发布订阅模式# 频道订阅 SUBSCRIBE news:sports # 客户端1订阅 PUBLISH news:sports "World Cup Final" # 客户端2发布 # 模式匹配(支持通配符) PSUBSCRIBE news.* # 订阅所有新闻频道 3. Lua脚本编程场景:原子操作、复杂事务-- 库存扣减脚本(避免超卖) local stock = tonumber(redis.call('GET', KEYS[1])) if stock and stock >= tonumber(ARGV[1]) then redis.call('DECRBY', KEYS[1], ARGV[1]) return 1 end return 0 执行方式:EVAL "script内容" 1 product:1001 5 # 参数:脚本、键数量、键、参数 4. 集群部署方案# 使用redis-cli创建3主3从集群 redis-cli --cluster create 192.168.1.1:6379 \ 192.168.1.2:6379 192.168.1.3:6379 \ 192.168.1.1:6380 192.168.1.2:6380 \ 192.168.1.3:6380 --cluster-replicas 1 # 集群管理命令 CLUSTER NODES # 查看节点信息 CLUSTER KEYSLOT "user:1001" # 计算键的槽位 四、生产环境最佳实践1. 性能优化技巧内存管理:# 查看内存使用详情 INFO memory # 使用压缩列表优化小集合存储 config set hash-max-ziplist-entries 512 连接池配置(Java示例):JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(100); // 最大连接数 poolConfig.setMaxIdle(20); // 最大空闲连接 JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379); 2. 安全防护措施防火墙规则:ufw allow from 192.168.1.0/24 to any port 6379 数据加密:使用Stunnel封装TLS连接考虑Twemproxy等代理层加密3. 监控告警方案Prometheus监控指标:# prometheus.yml配置 scrape_configs: - job_name: 'redis' static_configs: - targets: ['redis-server:9121'] # redis_exporter地址 关键监控项:instantaneous_ops_per_sec:QPSused_memory_rss:实际内存占用keyspace_hits:缓存命中率五、常见问题解决方案缓存穿透:方案:布隆过滤器 + 空值缓存# 使用Redis模块实现布隆过滤器 BF.ADD user:filter "non_exist_id" BF.EXISTS user:filter "non_exist_id" 缓存雪崩:方案:多级缓存 + 随机过期时间# 设置随机过期时间(Lua脚本示例) local expire = math.random(300, 900) redis.call('SETEX', KEYS[1], expire, ARGV[1]) 大Key处理:识别命令:redis-cli --bigkeys -i 0.1 # 扫描大键(低流量时段执行) 拆分方案:将大Hash拆分为多个小Hash结语Redis的强大不仅体现在其多样化的数据结构,更在于其作为分布式系统基石的生态体系。从本文介绍的单机部署到集群方案,开发者可以逐步构建起支持百万级QPS的缓存系统。建议进一步探索:Redis Stream实现消息队列RediSearch全文搜索引擎模块RedisTimeSeries时序数据库模块掌握Redis不仅是掌握一个缓存工具,更是获得了解高性能系统设计的关键视角。立即开始您的Redis实战之旅,解锁分布式系统的无限可能!
  • 华为云中间件部署和资源管理方面的问题
    各位专家,有几个关于华为云中间件部署和资源管理方面的问题,还请帮忙解答下:1.当前中间件组件(如 Kafka、Redis 等)是采用 Kubernetes 还是 Docker 进行容器化部署?底层运行环境是物理机还是虚拟机?2.当前中间件集群是通过 Operator 进行生命周期管理,还是使用了自研的平台产品?如果是后者,平台产品名称是什么,具备哪些管理能力?3.中间件组件的资源是否与其他业务系统共享?还是为其划分了独立的物理资源池或专属节点?是否存在混部的情况?
  • [技术干货] Redis Tag 字段详解与最佳实践 --转载
    一、在 RediSearch 中,Tag 字段(标签字段)是用来存储离散、可枚举值的高效索引类型。与全文(TEXT)字段不同,Tag 字段将整段文本视作由分隔符分隔的“标签列表”,并针对每个标签做最小化索引,从而在内存占用和查询速度上都更具优势。本文将深入介绍 Tag 字段的工作原理、创建方式、查询语法,以及常见场景下的最佳实践与注意事项。 二、Tag 字段核心特点简单分词默认使用逗号(,)或自定义分隔符,将整个字段拆分成若干独立标签,不做复杂的词干化或停用词处理。高压缩、低开销索引中仅存储文档 ID 的增量编码,不保存频率或偏移信息,通常每项索引仅占 1–2 字节。只能通过专用语法查询普通的无字段全文搜索(FT.SEARCH foo)不会命中 Tag 字段,必须使用 @field:{tag} 语法。支持多达 1024 个字段每个索引最多可定义 1024 个 Tag 字段,满足复杂场景需求。 三、创建 Tag 字段12345FT.CREATE idx:products ON HASH PREFIX 1 product:  SCHEMA    name   TEXT    price  NUMERIC    tags   TAG [SEPARATOR ";" ] [CASESENSITIVE]TAG:指定字段类型为标签。SEPARATOR ";":可选,定义不同标签之间的分隔符,默认为逗号(,)。CASESENSITIVE:可选,开启后标签大小写敏感,否则内部会统一小写处理。对于 JSON 索引,同样需要显式指定分隔符:123FT.CREATE idx:users ON JSON PREFIX 1 user:  SCHEMA    $.roles AS roles TAG SEPARATOR "|" 四、查询 Tag 字段 4.1 基本语法1FT.SEARCH idx "@tags:{admin}"花括号 {} 中列出要匹配的标签,可用管道符 | 表示「或」关系:1FT.SEARCH idx "@tags:{admin|editor|viewer}" 4.2 多标签查询:并集与交集并集(至少包含其一):在同一个 {} 内用 | 分隔:1FT.SEARCH idx "@tags:{news|tech|sports}"交集(同时包含所有):将同一字段的多次过滤串联:1FT.SEARCH idx "@tags:{news} @tags:{tech} @tags:{sports}" 4.3 前缀匹配Tag 字段支持星号 * 作为通配:12FT.SEARCH idx "@tags:{adm*}"        # 匹配所有以 adm 开头的标签FT.SEARCH idx "@tags:{hello\ w*}"   # 支持转义空格后的通配注意:在终端或编程环境中,反斜杠需双重转义(例如 \\ )。 五、标签中包含标点与空格标签本身可以包含除分隔符之外的任意可打印字符,包括空格和标点。但在查询时,涉及下列情况需要转义:单引号 '、反斜杠 \ 等特殊字符使用反斜杠 \ 转义:1FT.SEARCH idx "@tags:{Andrew\\'s Top 5}"空格在 RediSearch ≥2.4 或 DIALECT ≥2 时,标签内空格无需额外转义。在老版本或 DIALECT=1 时,需用反斜杠转义空格。 六、实战示例索引创建1234FT.CREATE travel ON HASH PREFIX 1 traveler:  SCHEMA    name   TEXT    cities TAG SEPARATOR ","数据插入12HSET traveler:1 name "Alice" cities "Paris,New York,Tokyo"HSET traveler:2 name "Bob"   cities "London,New York"查询示例访问过任意一座城市1FT.SEARCH travel "@cities:{New York|Paris}"同时访问过所有三座城市1FT.SEARCH travel "@cities:{Paris} @cities:{New York} @cities:{Tokyo}" 七、最佳实践与注意事项选择合适的分隔符根据标签数据特点,避免分隔符与标签内容冲突,例如使用 ;、| 等。开启 CASESENSITIVE 或 NOSTEM若标签是区分大小写或包含特殊格式,务必使用 CASESENSITIVE;否则可默认小写。索引覆盖若需返回标签列表本身,请在 LOAD 或 RETURN 中显式列出该字段,并在建索引时未遗漏。谨慎使用通配符前缀通配符虽然灵活,但会带来额外扫描开销,影响查询延迟。避免过度分片虽可定义多达 1024 个 Tag 字段,但每个字段都占用索引空间,根据应用场景合理规划字段数。
  • [优秀博文] Redis持久化机制深度解析:RDB与AOF的完美平衡
    Redis作为内存数据库,其持久化机制是确保数据安全的关键。本文将全面剖析Redis的两种持久化方式——RDB和AOF,帮助您根据业务场景选择最佳方案。一、Redis持久化概述Redis提供两种主要的持久化方式:RDB(Redis Database):定时生成数据快照AOF(Append Only File):记录所有写操作命令两种方式可单独使用,也可组合使用(Redis 4.0+推荐)二、RDB持久化详解核心机制通过SAVE(阻塞)或BGSAVE(后台)命令创建数据快照二进制压缩存储,文件名为dump.rdb触发方式# 手动触发 SAVE # 同步保存,阻塞其他操作 BGSAVE # 异步保存,fork子进程处理 # 自动触发(redis.conf配置) save 900 1 # 900秒内至少1个key变化 save 300 10 # 300秒内至少10个key变化 save 60 10000 # 60秒内至少10000个key变化 优势与局限优点:紧凑的单文件备份恢复速度快(大数据量场景优势明显)最大化Redis性能(不影响主进程)缺点:可能丢失最后一次快照后的数据大数据量时fork操作可能阻塞服务三、AOF持久化详解核心机制记录每个写操作命令(文本格式)支持三种同步策略:appendfsync always # 每个写命令都同步 appendfsync everysec # 每秒同步(默认) appendfsync no # 由操作系统决定 文件重写机制定期压缩AOF文件(移除冗余命令)触发方式:# 手动触发 BGREWRITEAOF # 自动触发(redis.conf配置) auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb优势与局限优点:数据安全性更高(最多丢失1秒数据)可读性强(文本格式)后台重写不影响服务缺点:文件体积通常大于RDB恢复速度较慢(需要重放所有命令)四、混合持久化(Redis 4.0+)创新方案结合RDB和AOF优势重写时先以RDB格式保存当前数据,再将增量命令以AOF格式追加配置方式:aof-use-rdb-preamble yes 五、生产环境最佳实践关键配置建议# RDB配置 dbfilename dump.rdb dir /var/lib/redis stop-writes-on-bgsave-error yes # AOF配置 appendonly yes appendfilename "appendonly.aof" 灾难恢复方案定期备份RDB/AOF文件到异地使用redis-check-aof和redis-check-rdb工具验证文件完整性性能调优技巧# 当内存超过此值时启用RDB压缩 rdbcompression yes rdbchecksum yes # AOF重写期间不做fsync no-appendfsync-on-rewrite yes 六、选型决策指南考量维度RDB优势场景AOF优势场景数据安全性允许分钟级丢失要求秒级保护恢复速度大数据量快速恢复小数据量适用写入性能更高稍低(取决于配置)存储空间更紧凑通常更大运维复杂度简单需要监控文件增长推荐方案:多数生产环境使用RDB+AOF混合模式,兼顾安全性与性能。七、常见问题排查Q:AOF文件过大怎么办?A:手动执行BGREWRITEAOF或调整自动重写阈值Q:持久化导致性能下降?A:检查磁盘IO性能,考虑使用SSD;调整appendfsync策略Q:如何从RDB切换到AOF?# 1. 备份当前RDB文件 # 2. 修改配置启用AOF # 3. 执行CONFIG SET appendonly yes # 4. 等待首次AOF文件生成 结语Redis的持久化机制如同数据的"双保险",理解其工作原理和适用场景对构建可靠系统至关重要。建议开发者根据业务对数据安全性和性能的要求,选择合适的持久化策略,并通过监控工具定期检查持久化状态,确保万无一失。
  • [技术干货] Redis过期策略详解:如何高效管理缓存生命周期
    Redis作为高性能的键值存储系统,其过期策略是缓存管理的核心功能之一。本文将深入解析Redis的过期机制,帮助开发者更好地利用这一特性优化应用性能。一、Redis过期策略概述Redis提供了两种主要的过期策略:被动过期(惰性删除)当客户端尝试访问一个键时,Redis会检查该键是否已过期如果过期则立即删除,返回空值优点:对CPU友好,不会主动消耗资源缺点:可能导致内存浪费(过期键未被访问时不会释放)主动过期(定期删除)Redis定期随机测试设置了过期时间的键删除已过期的键默认每秒运行10次(可配置)每次检查都会从过期字典中随机抽取20个键二、过期策略的底层实现Redis使用一个特殊的"过期字典"来存储所有设置了过期时间的键及其过期时间戳。这个数据结构保证了过期检查的高效性:typedef struct redisDb { dict *dict; // 键空间 dict *expires; // 过期字典 // ...其他字段 } redisDb; 三、过期命令使用指南Redis提供了多种设置过期时间的命令:# 设置键值对并指定过期时间(秒) SETEX key seconds value # 设置键值对并指定过期时间(毫秒) PSETEX key milliseconds value # 为已存在的键设置过期时间(秒) EXPIRE key seconds # 为已存在的键设置过期时间(毫秒) PEXPIRE key milliseconds # 查看键的剩余生存时间(秒) TTL key # 查看键的剩余生存时间(毫秒) PTTL key # 移除键的过期时间 PERSIST key四、最佳实践与性能优化合理设置过期时间根据业务特点设置不同的过期策略热点数据可以设置较长过期时间临时数据设置较短过期时间避免大量键同时过期可能导致Redis短时间内负载过高解决方案:为过期时间添加随机偏移量# 设置带有随机偏移量的过期时间 expire_time = 3600 + random.randint(0, 300) # 1小时±5分钟 redis_client.expire('key', expire_time) 监控与调优使用INFO stats命令监控过期键删除情况关注expired_keys指标了解过期键数量调整hz参数控制主动过期频率(默认10)五、常见问题解答Q:为什么我的键没有在预期时间被删除?A:Redis的过期删除是概率性的,可能存在短暂延迟。对于精确时间要求高的场景,建议结合业务逻辑处理。Q:如何清理大量已过期的键?A:可以使用SCAN命令配合TTL检查,手动删除已过期键,或考虑在低峰期重启Redis实例。Q:过期键会占用内存吗?A:会,直到被主动或被动删除为止。定期检查内存使用情况很重要。六、总结Redis的过期策略是其作为缓存系统的核心功能之一。理解并合理利用这些机制,可以帮助开发者构建更高效、更可靠的应用程序。通过结合被动和主动过期策略,Redis在内存管理和性能之间取得了良好的平衡。在实际应用中,建议根据具体业务场景调整过期策略,并定期监控Redis的内存使用情况和过期键删除效率,以确保系统始终处于最佳状态。
  • [技术干货] 【技术合集】数据库板块2025年6月合集
    本月围绕数据库Mysql与 Redis与MongDB应用和理论,撰写了 多篇技术博客,内容涵盖原理讲解、部署实操、架构对比及高阶用法,适合有一定开发经验的同学系统性提升。具体内容如下:MongoDB Schema设计进阶https://bbs.huaweicloud.com/forum/thread-0242186151481963009-1-1.htmlRedis缓存三大经典问题:穿透、击穿、雪崩的防御体系与实践方案https://bbs.huaweicloud.com/forum/thread-0270186151287006008-1-1.htmlMySQL Online DDL演进https://bbs.huaweicloud.com/forum/thread-0270186149379800007-1-1.htmlMongoDB分片集群设计精要https://bbs.huaweicloud.com/forum/thread-0245186146589994004-1-1.htmlRedis Pipeline与事务https://bbs.huaweicloud.com/forum/thread-0270186139908337005-1-1.htmlGaussDB全局事务管理https://bbs.huaweicloud.com/forum/thread-0265186139485857004-1-1.htmlMySQL主从复制延迟:深度剖析与全方位优化指南https://bbs.huaweicloud.com/forum/thread-0270186139258938004-1-1.htmlMongoDB聚合框架https://bbs.huaweicloud.com/forum/thread-02111186137859433003-1-1.htmlRedis内存淘汰策略深度解析https://bbs.huaweicloud.com/forum/thread-0270186135899969003-1-1.html📌 本月技术内容聚焦 Redis、Mysql、MongDB,既有底层原理的讲解,也有实战落地的操作方案,欢迎阅读、收藏、转发,如有问题欢迎留言交流,下月见!🚀
  • [技术干货] 键的过期清除机制与内存淘汰策略
    在 Redis 中,键的过期清除机制与内存淘汰策略是两个不同但相关的概念。理解它们的工作原理对于优化 Redis 内存使用和数据可靠性至关重要。一、Redis 的过期键清除机制当一个 key 设置了过期时间后,Redis 并不一定会立即清除它,而是采用 ** 惰性删除(Lazy Expiration)和定期删除(Periodic Expiration)** 两种策略结合的方式:1. 惰性删除(访问时检查)触发条件:当客户端尝试访问(如GET、HGET)一个 key 时,Redis 会首先检查该 key 是否过期。执行动作若已过期,Redis 会立即删除该 key,并返回nil给客户端。若未过期,正常返回 key 对应的值。优点:避免无用的 CPU 消耗,只在需要时清理过期键。缺点:若过期键长期未被访问,会持续占用内存(成为 “僵尸键”)。2. 定期删除(主动扫描)触发条件:Redis 每秒会进行 10 次(默认配置hz 10)的过期键扫描,具体频率可通过config set hz <value>调整。执行流程从每个数据库中随机选择 20 个 key。删除其中过期的 key。如果过期 key 的比例超过 25%,重复步骤 1-2。优点:定期清理未被访问的过期键,释放内存。缺点:若过期键过多,可能导致扫描耗时增加,影响 Redis 性能。二、过期键未被及时清除的场景即使 key 已过期,在以下情况下仍可能未被立即清除:未触发惰性删除:过期后没有客户端访问该 key。定期删除未覆盖该 key 未被随机选中进行检查。同一时间过期的 key 过多,导致部分未被清理(受限于每次扫描的 20 个 key)。内存压力不足:当 Redis 内存使用未达到上限时,过期键可能不会被优先清理。三、Redis 的内存淘汰策略(Eviction Policies)当 Redis 内存使用达到上限(maxmemory配置)时,会触发内存淘汰策略。Redis 提供 8 种淘汰策略,默认策略为noeviction:1. 默认策略:noeviction行为:当内存不足时,拒绝所有写操作(如SET、LPUSH),只允许读操作。适用场景:不允许数据丢失的场景,但可能导致应用频繁报错。2. 其他常用策略volatile-lru(最常用):行为:优先删除最近最少使用(LRU)的过期键。适用场景:希望保留热点数据,同时清理过期键的场景。allkeys-lru行为:删除最近最少使用(LRU)的键,无论是否过期。适用场景:缓存所有数据(不设置过期时间),且需要淘汰冷数据的场景。volatile-random行为:随机删除过期键。适用场景:对数据淘汰顺序无特殊要求的场景。allkeys-random行为:随机删除任意键。适用场景:数据价值均等,随机淘汰不影响业务的场景。volatile-ttl行为:优先删除剩余时间(TTL)最短的过期键。适用场景:需要尽快释放内存的场景。3. LRU 近似算法Redis 使用近似 LRU 算法(而非严格 LRU),通过随机采样(默认 5 个 key)来估算最久未使用的 key。可通过maxmemory-samples配置调整采样数量(值越大越接近严格 LRU,但消耗更多 CPU)。四、配置与优化建议1. 修改淘汰策略通过配置文件(redis.conf)或命令行修改:# 修改配置文件 maxmemory 2gb # 设置最大内存 maxmemory-policy volatile-lru # 设置淘汰策略 # 或使用命令行动态修改 redis-cli config set maxmemory 2gb redis-cli config set maxmemory-policy volatile-lru2. 过期键清理优化调整扫描频率:对过期键较多的场景,增加hz值(如hz 20),提高定期删除的频率。避免大量键同时过期:分散过期时间(如在基础 TTL 上添加随机偏移量),减少扫描压力。3. 淘汰策略选择建议业务场景推荐策略说明缓存场景(有过期时间)volatile-lru保留热点数据,淘汰冷数据缓存场景(无过期时间)allkeys-lru强制淘汰冷数据,确保新数据能存入希望尽快释放内存volatile-ttl优先淘汰即将过期的键数据价值均等allkeys-random随机淘汰,适用于无明显热点的数据不允许数据丢失noeviction写满时报错,需手动清理或扩容五、总结:过期键与淘汰策略的关系过期键清除:由惰性删除和定期删除机制处理,确保过期键最终被清理。内存淘汰策略:在内存不足时触发,决定哪些键被优先删除。关键点:即使设置了过期时间,若未触发清除机制且内存充足,过期键可能仍存在于内存中;而当内存不足时,淘汰策略会优先处理过期键(如volatile-lru)或任意键(如allkeys-lru)。
  • [技术干货] 【技术合集】数据库板块2025年6月合集
    本月围绕数据库基础知识与 Redis 实战应用,撰写了 9 篇技术博客,内容涵盖原理讲解、部署实操、架构对比及高阶用法,适合有一定开发经验的同学系统性提升。具体内容如下:1. 《CHAR 和 VARCHAR 的区别》深入解析 CHAR 与 VARCHAR 的底层存储差异、性能表现与使用场景,帮助开发者在建表时合理选择字段类型。https://bbs.huaweicloud.com/forum/thread-0245186243529207008-1-1.html2. 《关系型数据库和非关系型数据库的区别》从数据结构、事务支持、扩展能力等角度出发,系统对比 RDBMS 与 NoSQL,帮助理解数据库选型策略。https://bbs.huaweicloud.com/forum/thread-0245186243219296007-1-1.html3. 《CentOS7 部署 Redis 以及多实例》介绍如何在 CentOS7 环境下从零部署 Redis,并实现多实例并行运行,适用于开发测试与生产部署。https://bbs.huaweicloud.com/forum/thread-0291185639586016026-1-1.html4. 《SpringBoot 整合 Redis 过期 Key 监听实现订单过期操作》利用 Redis 的 Key 过期事件,结合 SpringBoot 实现订单自动超时关闭,适用于秒杀、电商类系统的延迟任务处理。https://bbs.huaweicloud.com/forum/thread-02112185639431404024-1-1.html5. 《SpringBoot 整合 Redis 及 Lua 脚本实现接口限流》借助 Redis + Lua 实现高性能限流方案,有效应对高并发场景,防止接口被恶意频繁调用。https://bbs.huaweicloud.com/forum/thread-02101185639208978023-1-1.html6. 《位运算的魅力:使用 Redis Bitmap 高效处理百万级布尔值》通过 Redis Bitmap 技术处理大规模布尔状态数据,如签到打卡、行为记录,兼顾空间与性能。https://bbs.huaweicloud.com/forum/thread-0234185274120133013-1-1.html7. 《内存淘金术:Redis 内存满了怎么办?》探讨 Redis 内存满时的应对策略,详解淘汰机制、内存管理参数配置及优化建议。https://bbs.huaweicloud.com/forum/thread-02127185273941874026-1-1.html8. 《Redis-Cluster 与 Redis 集群的技术大比拼》从架构设计、容灾能力、扩展性等角度比较 Redis 原生 Cluster 与传统主从集群,适合集群选型参考。https://bbs.huaweicloud.com/forum/thread-02101185273817208015-1-1.html9. 《Redis Geo:掌握地理空间数据的艺术》基于 Redis 的 Geo 类型,实现位置存储、距离计算、范围查询等地理功能,常用于附近的人、门店推荐等业务。https://bbs.huaweicloud.com/forum/thread-0291185273720015014-1-1.html📌 本月技术内容聚焦 Redis 的核心能力与进阶实践,既有底层原理的讲解,也有实战落地的操作方案,欢迎阅读、收藏、转发,如有问题欢迎留言交流,下月见!🚀
  • redis maxmemory-policy策略
    Redis 的 maxmemory-policy 是内存管理的核心策略,用于在内存接近或超过 maxmemory 限制时,自动淘汰(Evict)键以释放空间。正确配置该策略能避免 OOM(Out of Memory)错误,并优化缓存命中率。以下是 详细解析,涵盖策略类型、选择依据、配置方法及实战案例。一、为什么需要 maxmemory-policy?当 Redis 的内存使用达到 maxmemory 限制时,若没有淘汰策略,会触发以下行为:noeviction(默认):拒绝所有写入命令(如 SET、HSET),返回错误:(error) OOM command not allowed when used memory > 'maxmemory'. 其他策略:根据规则淘汰键,腾出空间后执行写入。关键目标:在内存受限时,平衡数据新鲜度、命中率和系统稳定性。二、8 种淘汰策略详解Redis 支持 8 种淘汰策略,分为 3 大类:1. 不淘汰键(禁止写入)noeviction行为:直接拒绝写入,返回 OOM 错误。适用场景:数据绝对不能丢失(如金融交易记录)。配合外部监控,手动扩容或清理数据。风险:可能导致业务中断。配置示例:redis-cli CONFIG SET maxmemory-policy noeviction2. 淘汰有过期时间的键(Volatile Keys)volatile-lru行为:淘汰有过期时间的键中,最近最少使用(LRU)的键。适用场景:缓存场景,且大部分键设置了过期时间(如会话缓存)。示例:# 设置键的过期时间 redis-cli SET user:1000 "Alice" EX 3600 # 1小时后过期 redis-cli SET temp:data "tmp" EX 60 # 1分钟后过期 当内存不足时,优先淘汰 temp:data(假设它未被访问)。volatile-lfu行为:淘汰有过期时间的键中,最不经常使用(LFU)的键。适用场景:热点数据频繁访问,冷数据需优先淘汰(如推荐系统缓存)。配置要求:Redis 4.0+。volatile-ttl行为:淘汰剩余 TTL(生存时间)最短的键。适用场景:希望优先保留长生存时间的键(如后台任务队列)。示例:# 键 A 剩余 TTL 10分钟,键 B 剩余 TTL 1分钟 # 内存不足时,优先淘汰键 B volatile-random行为:随机淘汰有过期时间的键。适用场景:无热点数据,均匀淘汰以避免突发流量冲击。3. 淘汰所有键(All Keys)allkeys-lru行为:淘汰所有键中的最近最少使用(LRU)的键(无论是否有过期时间)。适用场景:缓存无严格过期时间的数据(如商品详情)。优势:比 volatile-lru 更彻底,避免因键未设置过期时间导致无法淘汰。allkeys-lfu行为:淘汰所有键中的最不经常使用(LFU)的键。适用场景:长期存储的数据中,区分热点和冷数据(如用户画像)。allkeys-random行为:随机淘汰所有键。适用场景:数据访问均匀,无热点(如日志缓存)。三、策略选择指南1. 根据数据特性选择数据类型推荐策略理由缓存(带过期时间)volatile-lru 或 volatile-ttl优先淘汰即将过期的键,避免无效占用内存。缓存(无过期时间)allkeys-lru确保热点数据保留,冷数据被淘汰。热点数据敏感(如推荐系统)allkeys-lfu保留高频访问数据,提升命中率。均匀访问数据allkeys-random 或 volatile-random避免 LRU/LFU 的计算开销。绝对不能丢失数据noeviction + 监控扩容通过外部系统(如 Prometheus)监控内存,手动触发扩容或清理。2. 性能与精度权衡LRU/LFU 的近似算法:Redis 使用 随机采样 实现近似 LRU/LFU(非精确),通过 maxmemory-samples 参数控制采样数量(默认 5):# 增加采样数以提高准确性(但增加 CPU 开销) redis-cli CONFIG SET maxmemory-samples 10 随机策略的性能:*-random 策略无需维护访问记录,CPU 开销最低,但命中率可能下降。四、配置与动态调整1. 永久配置(redis.conf)# 设置内存上限和策略 maxmemory 4gb maxmemory-policy allkeys-lru # 可选:调整 LRU/LFU 采样数 maxmemory-samples 10 2. 动态修改(无需重启)# 查看当前策略 redis-cli CONFIG GET maxmemory-policy # 修改策略(例如改为 volatile-ttl) redis-cli CONFIG SET maxmemory-policy volatile-ttl3. 集群模式注意事项每个节点独立配置 maxmemory-policy。确保所有节点的策略一致,避免数据分布不均。五、实战案例案例 1:电商缓存优化场景:电商平台使用 Redis 缓存商品详情(无过期时间),内存限制为 8GB。业务高峰期内存占用达 9GB,触发 OOM。优化步骤:选择策略:redis-cli CONFIG SET maxmemory-policy allkeys-lru调整采样数:redis-cli CONFIG SET maxmemory-samples 15 # 提高 LRU 准确性 监控效果:watch -n 1 "redis-cli info memory | grep -E 'used_memory|evicted_keys'" 结果:内存稳定在 7.5GB,无 OOM。evicted_keys 显示淘汰了低访问量的商品数据。案例 2:会话缓存(Session Store)场景:Web 应用使用 Redis 存储用户会话(设置 30 分钟过期),内存限制为 2GB。需确保活跃会话不被淘汰。优化步骤:选择策略:redis-cli CONFIG SET maxmemory-policy volatile-ttl验证策略:# 模拟写入会话 redis-cli SET session:user1 "data" EX 1800 redis-cli SET session:user2 "data" EX 60 # 短过期时间 # 触发内存压力(通过其他操作填满内存) # 观察 user2 的会话优先被淘汰 六、常见问题与调试1. 策略未生效?检查 maxmemory:redis-cli CONFIG GET maxmemory若未设置或为 0,则策略不触发。检查键是否有过期时间:redis-cli TTL my_key # 返回 -2 表示无过期时间 若使用 volatile-* 策略但键无过期时间,则不会淘汰。2. 如何评估策略效果?监控指标:evicted_keys:累计淘汰的键数量。keyspace_hits / keyspace_misses:命中率。redis-cli info stats | grep -E 'evicted_keys|keyspace_' 调整策略:若命中率低且 evicted_keys 高,可能需改用 allkeys-lru 或增加内存。3. LFU 与 LRU 如何选择?LFU 优势:适合访问模式稳定的数据(如用户偏好设置)。LRU 优势:适合访问模式变化快的数据(如新闻热点)。七、总结策略分类推荐策略核心逻辑适用场景禁止写入noeviction拒绝写入,返回错误数据绝对不能丢失淘汰过期键volatile-lru/volatile-ttl优先淘汰过期键中的冷数据缓存带过期时间的数据淘汰所有键allkeys-lru/allkeys-lfu淘汰全局冷数据缓存无过期时间的数据最佳实践:缓存场景:优先用 volatile-lru 或 allkeys-lru。热点数据:用 allkeys-lfu 提升命中率。均匀访问:用 *-random 降低 CPU 开销。监控:结合 evicted_keys 和命中率调整策略。通过合理选择 maxmemory-policy,可显著提升 Redis 的稳定性和性能。