使用索引、管道(Pipeline)、Lua脚本、多线程客户端和预热数据是Redis快速查询的主要方法。高效查库操作包括:SORT、SCAN、HSCAN、SSCAN等渐进式迭代命令,避免KEYS命令;利用GEO、HyperLogLog等高级数据结构;开启持久化AOF+RDB结合使用;设置合理的过期时间和内存限制。
1. 索引和数据结构选择
在Redis中,快速查询的关键在于选择合适的数据结构。对于精确查找,使用Hash或Set;对于范围查询,使用Sorted Set;地理位置查询用GEO。示例:ZADD myset 1 "value1" 2 "value2",然后ZRANGEBYSCORE myset 0 +inf。
2. 管道和批量操作
Pipeline可以将多个命令打包发送,减少网络RTT。例如在Java中使用Jedis:Pipeline p = jedis.pipelined(); p.set("key", "value"); p.get("key"); List
3. Lua脚本原子执行
使用EVAL脚本实现复杂查询原子性,避免多次往返。示例:local key=KEYS[1] local val=ARGV[1] if redis.call('EXISTS',key)==1 then return redis.call('GET',key) else return 'nil' end,执行EVAL script 1 key value。
4. 渐进式扫描
不要用KEYS *,改用SCAN 0 MATCH "prefix*" COUNT 1000,能迭代查询海量key,避免阻塞主进程。Hash用HSCAN,Set用SSCAN。
5. 集群和哨兵优化
在集群模式下,使用HASH TAG确保相关key落在同一槽:{user1001}:name、{user1001}:age。哨兵模式下,客户端自动切换主从,实现高可用查询。
6. 内存优化
设置maxmemory-policy allkeys-lru,定期用redis-cli --bigkeys检查大key;使用bit字段或HyperLogLog节省空间;预热热门数据到内存。
FAQ
Q: Redis为什么比MySQL查询快?
A: Redis是内存数据库,单线程避免锁竞争,数据结构优化了常见查询场景。
Q: KEYS命令为什么不能用在生产?
A: 它会阻塞整个Redis实例,线上大数据量时可能卡死服务。
Q: Pipeline和Transaction区别?
A: Pipeline非原子但高效,Transaction是原子但有WATCH开销。
Q: 如何查询GEO位置最近的点?
A: GEOADD china:city 116.40 39.90 "beijing",然后GEORADIUS china:city 116.40 39.90 100 km。