第一次接触Redis是在2013年一个电商促销系统架构中,当时我们需要一个能支撑每秒10万次查询的缓存层。传统数据库在压力测试时响应时间从50ms直接飙升到2秒以上,而引入Redis后,即使在峰值期也能稳定保持在5ms以内。这种性能差异让我彻底理解了内存数据库的革命性意义。
Redis(Remote Dictionary Server)本质上是一个开源的键值存储系统,但它的能力远不止简单的缓存。现代应用系统中,Redis至少解决三类核心问题:
在电商秒杀系统中,我们用String类型缓存商品库存,用List实现抢购排队,用SortedSet做排行榜,再用事务保证库存扣减的原子性——这些功能在传统数据库中需要复杂实现,而Redis原生支持。
在Ubuntu 22.04上推荐从源码编译安装,能获得最佳性能:
bash复制wget https://download.redis.io/redis-stable.tar.gz
tar -xzvf redis-stable.tar.gz
cd redis-stable
make BUILD_TLS=yes -j$(nproc)
sudo make install
关键编译参数说明:
BUILD_TLS=yes 启用SSL加密传输-j$(nproc) 使用全部CPU核心并行编译redis.conf中这几个参数直接影响性能:
conf复制maxmemory 16gb # 建议物理内存的3/4
maxmemory-policy allkeys-lru
hash-max-ziplist-entries 512
set-max-intset-entries 512
重要提示:在Linux系统必须设置
vm.overcommit_memory=1,否则在内存不足时可能导致后台保存失败。通过sysctl vm.overcommit_memory=1立即生效。
| 类型 | 时间复杂度 | 典型场景 | 内存优化技巧 |
|---|---|---|---|
| String | O(1) | 缓存、计数器 | 使用数字类型替代字符串 |
| Hash | O(1) | 对象属性存储 | 控制field数量在512个以内 |
| List | O(N) | 消息队列、最新列表 | 限制列表长度避免阻塞 |
| Set | O(1) | 去重、好友关系 | 小集合用intset编码 |
| Sorted Set | O(logN) | 排行榜、延迟队列 | 调整zset-max-ziplist-entries |
错误的实现方式:
python复制stock = redis.get('item_123')
if stock > 0:
redis.decr('item_123')
这在高并发下会出现超卖问题。正确做法是使用Lua脚本保证原子性:
lua复制local key = KEYS[1]
local change = tonumber(ARGV[1])
local current = tonumber(redis.call('GET', key))
if current >= change then
return redis.call('INCRBY', key, -change)
end
return -1
三主三从集群配置示例:
bash复制redis-cli --cluster create \
192.168.1.101:6379 192.168.1.102:6379 192.168.1.103:6379 \
192.168.1.104:6379 192.168.1.105:6379 192.168.1.106:6379 \
--cluster-replicas 1
关键参数验证:
bash复制redis-cli --cluster check 192.168.1.101:6379
使用redis-benchmark测试集群:
bash复制redis-benchmark -h 192.168.1.101 -p 6379 -t set,get -n 1000000 -c 500 -P 16
优化前后对比(AWS c5.2xlarge实例):
| 指标 | 单节点 | 集群(3主) | 优化手段 |
|---|---|---|---|
| QPS(set) | 85,000 | 240,000 | Pipeline批处理 |
| 平均延迟 | 1.2ms | 0.8ms | 客户端连接池优化 |
| 99%延迟 | 5ms | 3ms | 禁用透明大页(THP) |
错误配置:
conf复制expire item_123 3600 # 所有key同时过期
正确做法:
python复制import random
expire_time = 3600 + random.randint(0, 300) # 增加随机过期时间
redis.expire('item_123', expire_time)
使用redis-cli监控热点Key:
bash复制redis-cli --hotkeys --bigkeys
解决方案对比:
相比Pub/Sub的优势:
生产者示例:
bash复制XADD orders * item_id 123 user_id 456
消费者组创建:
bash复制XGROUP CREATE orders inventory_group $ MKSTREAM
建立商品索引:
bash复制FT.CREATE item_idx
ON HASH
PREFIX 1 item_
SCHEMA
title TEXT WEIGHT 5.0
price NUMERIC SORTABLE
搜索示例:
bash复制FT.SEARCH item_idx "手机 -小米"
SORTBY price DESC
LIMIT 0 10
在内存足够的情况下,RedisSearch的搜索性能可以达到Elasticsearch的5-8倍,特别适合实时性要求高的场景。