Redis基础命令速查:从连接到数据操作,新手也能上手
Redis基础命令速查:从连接到数据操作,新手也能上手
1. Redis命令概览
1.1 命令分类表
命令类别 | 描述 | 主要命令 | 使用频率 |
---|---|---|---|
连接命令 | 客户端连接管理 | PING, AUTH, SELECT | ⭐⭐⭐⭐⭐ |
键命令 | 通用键操作 | EXISTS, DEL, EXPIRE, TTL | ⭐⭐⭐⭐⭐ |
字符串命令 | 字符串类型操作 | SET, GET, INCR, APPEND | ⭐⭐⭐⭐⭐ |
哈希命令 | 哈希表操作 | HSET, HGET, HGETALL | ⭐⭐⭐⭐ |
列表命令 | 列表操作 | LPUSH, RPUSH, LRANGE | ⭐⭐⭐⭐ |
集合命令 | 集合操作 | SADD, SMEMBERS, SINTER | ⭐⭐⭐ |
有序集合命令 | 有序集合操作 | ZADD, ZRANGE, ZSCORE | ⭐⭐⭐ |
服务器命令 | 服务器管理 | INFO, CONFIG, SAVE | ⭐⭐ |
1.2 返回值类型
返回值类型 | 描述 | 示例 |
---|---|---|
状态回复 | 简单字符串 | OK , PONG |
整数回复 | 数字 | 1 , 0 , 100 |
批量回复 | 字符串或nil | "hello" , (nil) |
多批量回复 | 数组 | ["item1", "item2"] |
2. 连接与认证命令
2.1 PING - 测试连接
# 基本ping
127.0.0.1:6379> PING
PONG# 带消息的ping
127.0.0.1:6379> PING "hello"
"hello"
2.2 AUTH - 身份认证
127.0.0.1:6379> AUTH mypassword
OK
2.3 SELECT - 选择数据库
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]>
3. 通用键操作命令
3.1 EXISTS - 检查键是否存在
127.0.0.1:6379> SET mykey "hello"
OK
127.0.0.1:6379> EXISTS mykey
(integer) 1127.0.0.1:6379> EXISTS notexist
(integer) 0
3.2 TYPE - 获取键的数据类型
127.0.0.1:6379> SET stringkey "hello"
OK
127.0.0.1:6379> TYPE stringkey
string127.0.0.1:6379> LPUSH listkey "item"
(integer) 1
127.0.0.1:6379> TYPE listkey
list
3.3 DEL - 删除键
127.0.0.1:6379> DEL mykey
(integer) 1127.0.0.1:6379> DEL key1 key2 key3
(integer) 3
3.4 过期时间管理
EXPIRE - 设置过期时间
127.0.0.1:6379> SET mykey "hello"
OK
127.0.0.1:6379> EXPIRE mykey 60
(integer) 1
TTL - 查看剩余时间
127.0.0.1:6379> TTL mykey
(integer) 58# 特殊返回值
127.0.0.1:6379> TTL notexist
(integer) -2 # 键不存在127.0.0.1:6379> TTL persistkey
(integer) -1 # 无过期时间
3.5 KEYS vs SCAN
KEYS(生产环境慎用)
127.0.0.1:6379> KEYS user:*
1) "user:1001"
2) "user:1002"
SCAN(推荐)
127.0.0.1:6379> SCAN 0 MATCH user:* COUNT 100
1) "0"
2) 1) "user:1001"2) "user:1002"
4. 字符串操作命令
4.1 基本操作
SET/GET
# 基本设置
127.0.0.1:6379> SET mykey "hello"
OK# 带过期时间
127.0.0.1:6379> SET mykey "hello" EX 60
OK# 条件设置
127.0.0.1:6379> SET mykey "hello" NX # 不存在时设置
127.0.0.1:6379> SET mykey "world" XX # 存在时设置# 获取值
127.0.0.1:6379> GET mykey
"hello"
批量操作
# 批量设置
127.0.0.1:6379> MSET key1 "value1" key2 "value2"
OK# 批量获取
127.0.0.1:6379> MGET key1 key2 key3
1) "value1"
2) "value2"
3) (nil)
4.2 数值操作
# 自增/自减
127.0.0.1:6379> SET counter 10
OK
127.0.0.1:6379> INCR counter
(integer) 11
127.0.0.1:6379> DECR counter
(integer) 10# 按指定值增减
127.0.0.1:6379> INCRBY counter 5
(integer) 15
127.0.0.1:6379> DECRBY counter 3
(integer) 12
4.3 字符串操作
# 追加字符串
127.0.0.1:6379> SET mykey "hello"
OK
127.0.0.1:6379> APPEND mykey " world"
(integer) 11
127.0.0.1:6379> GET mykey
"hello world"# 获取长度
127.0.0.1:6379> STRLEN mykey
(integer) 11
5. 哈希操作命令
5.1 基本哈希操作
# 设置字段
127.0.0.1:6379> HSET user:1001 name "alice"
(integer) 1
127.0.0.1:6379> HSET user:1001 age 25 city "beijing"
(integer) 2# 获取字段值
127.0.0.1:6379> HGET user:1001 name
"alice"# 批量操作
127.0.0.1:6379> HMSET user:1002 name "bob" age 30
OK
127.0.0.1:6379> HMGET user:1002 name age
1) "bob"
2) "30"# 获取所有字段
127.0.0.1:6379> HGETALL user:1001
1) "name"
2) "alice"
3) "age"
4) "25"
5) "city"
6) "beijing"# 删除字段
127.0.0.1:6379> HDEL user:1001 city
(integer) 1# 检查字段存在
127.0.0.1:6379> HEXISTS user:1001 name
(integer) 1
6. 列表操作命令
6.1 基本列表操作
# 左右插入
127.0.0.1:6379> LPUSH mylist "a" "b" "c"
(integer) 3
127.0.0.1:6379> RPUSH mylist "d" "e"
(integer) 5# 左右弹出
127.0.0.1:6379> LPOP mylist
"c"
127.0.0.1:6379> RPOP mylist
"e"# 获取范围
127.0.0.1:6379> LRANGE mylist 0 -1
1) "b"
2) "a"
3) "d"# 获取长度
127.0.0.1:6379> LLEN mylist
(integer) 3# 按索引获取
127.0.0.1:6379> LINDEX mylist 0
"b"# 按索引设置
127.0.0.1:6379> LSET mylist 0 "new_first"
OK
7. 集合操作命令
7.1 基本集合操作
# 添加成员
127.0.0.1:6379> SADD myset "a" "b" "c"
(integer) 3# 获取所有成员
127.0.0.1:6379> SMEMBERS myset
1) "a"
2) "b"
3) "c"# 检查成员
127.0.0.1:6379> SISMEMBER myset "a"
(integer) 1# 移除成员
127.0.0.1:6379> SREM myset "a"
(integer) 1# 获取大小
127.0.0.1:6379> SCARD myset
(integer) 2
7.2 集合运算
127.0.0.1:6379> SADD set1 "a" "b" "c"
(integer) 3
127.0.0.1:6379> SADD set2 "b" "c" "d"
(integer) 3# 交集
127.0.0.1:6379> SINTER set1 set2
1) "b"
2) "c"# 并集
127.0.0.1:6379> SUNION set1 set2
1) "a"
2) "b"
3) "c"
4) "d"# 差集
127.0.0.1:6379> SDIFF set1 set2
1) "a"
8. 有序集合操作命令
8.1 基本有序集合操作
# 添加成员
127.0.0.1:6379> ZADD myzset 100 "alice" 200 "bob" 150 "charlie"
(integer) 3# 按分数排序获取
127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "alice"
2) "100"
3) "charlie"
4) "150"
5) "bob"
6) "200"# 获取分数
127.0.0.1:6379> ZSCORE myzset "alice"
"100"# 获取排名
127.0.0.1:6379> ZRANK myzset "alice"
(integer) 0# 按分数范围获取
127.0.0.1:6379> ZRANGEBYSCORE myzset 100 150
1) "alice"
2) "charlie"
9. 服务器信息命令
9.1 INFO - 获取服务器信息
# 获取内存信息
127.0.0.1:6379> INFO memory
# Memory
used_memory:1000000
used_memory_human:976.56K# 获取服务器信息
127.0.0.1:6379> INFO server
# Server
redis_version:7.0.0
redis_git_sha1:00000000
9.2 CONFIG - 配置管理
# 获取配置
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"# 设置配置
127.0.0.1:6379> CONFIG SET maxmemory 1gb
OK
10. 实战案例与Java代码
10.1 用户会话管理
@Service
public class SessionService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 创建用户会话*/public String createSession(String userId, Map<String, Object> sessionData) {String sessionId = UUID.randomUUID().toString();String sessionKey = "session:" + sessionId;// 存储会话数据redisTemplate.opsForHash().putAll(sessionKey, sessionData);// 设置过期时间30分钟redisTemplate.expire(sessionKey, 30, TimeUnit.MINUTES);return sessionId;}/*** 获取会话数据*/public Map<Object, Object> getSession(String sessionId) {String sessionKey = "session:" + sessionId;Map<Object, Object> session = redisTemplate.opsForHash().entries(sessionKey);// 续期if (!session.isEmpty()) {redisTemplate.expire(sessionKey, 30, TimeUnit.MINUTES);}return session;}/*** 删除会话*/public void deleteSession(String sessionId) {String sessionKey = "session:" + sessionId;redisTemplate.delete(sessionKey);}
}
10.2 商品库存管理
@Service
public class InventoryService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 初始化商品库存*/public void initStock(String productId, int stock) {String key = "stock:" + productId;redisTemplate.opsForValue().set(key, stock);}/*** 减少库存(原子操作)*/public boolean decreaseStock(String productId, int quantity) {String key = "stock:" + productId;// 使用Lua脚本保证原子性String script = "local stock = redis.call('get', KEYS[1]) " +"if stock and tonumber(stock) >= tonumber(ARGV[1]) then " +"return redis.call('decrby', KEYS[1], ARGV[1]) " +"else " +"return -1 " +"end";DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();redisScript.setScriptText(script);redisScript.setResultType(Long.class);Long result = redisTemplate.execute(redisScript, Collections.singletonList(key), quantity);return result != null && result >= 0;}/*** 获取当前库存*/public int getCurrentStock(String productId) {String key = "stock:" + productId;Object stock = redisTemplate.opsForValue().get(key);return stock != null ? Integer.parseInt(stock.toString()) : 0;}
}
10.3 排行榜系统
@Service
public class RankingService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String RANKING_KEY = "game:ranking";/*** 更新用户分数*/public void updateScore(String userId, double score) {redisTemplate.opsForZSet().add(RANKING_KEY, userId, score);}/*** 增加用户分数*/public Double incrementScore(String userId, double delta) {return redisTemplate.opsForZSet().incrementScore(RANKING_KEY, userId, delta);}/*** 获取排行榜TOP N*/public List<RankingItem> getTopRanking(int topN) {Set<ZSetOperations.TypedTuple<String>> tuples = redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, topN - 1);List<RankingItem> rankings = new ArrayList<>();int rank = 1;for (ZSetOperations.TypedTuple<String> tuple : tuples) {RankingItem item = new RankingItem();item.setRank(rank++);item.setUserId(tuple.getValue());item.setScore(tuple.getScore());rankings.add(item);}return rankings;}/*** 获取用户排名*/public Long getUserRank(String userId) {Long rank = redisTemplate.opsForZSet().reverseRank(RANKING_KEY, userId);return rank != null ? rank + 1 : null;}
}@Data
public class RankingItem {private Integer rank;private String userId;private Double score;
}
10.4 分布式计数器
@Service
public class CounterService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 页面访问计数*/public Long incrementPageView(String pageId) {String key = "pv:" + pageId;return redisTemplate.opsForValue().increment(key);}/*** 用户点赞计数*/public Long incrementLike(String contentId) {String key = "like:" + contentId;return redisTemplate.opsForValue().increment(key);}/*** 获取计数值*/public Long getCount(String key) {String value = redisTemplate.opsForValue().get(key);return value != null ? Long.parseLong(value) : 0L;}/*** 批量获取计数*/public Map<String, Long> getCountBatch(List<String> keys) {List<String> values = redisTemplate.opsForValue().multiGet(keys);Map<String, Long> result = new HashMap<>();for (int i = 0; i < keys.size(); i++) {String value = values.get(i);result.put(keys.get(i), value != null ? Long.parseLong(value) : 0L);}return result;}
}
11. 命令性能对比与注意事项
11.1 命令性能对比
命令类型 | 时间复杂度 | 性能影响 | 使用建议 |
---|---|---|---|
GET/SET | O(1) | 很低 | 可频繁使用 |
MGET/MSET | O(N) | 低 | 优于多次单独操作 |
KEYS | O(N) | 很高 | 生产环境禁用 |
SCAN | O(1) | 低 | 替代KEYS使用 |
HGETALL | O(N) | 中 | 大hash慎用 |
LRANGE | O(S+N) | 中 | 控制范围大小 |
ZRANGE | O(log(N)+M) | 中 | 控制返回数量 |
11.2 使用注意事项
11.2.1 避免使用的命令
# ❌ 危险命令 - 会阻塞服务器
KEYS * # 使用SCAN代替
FLUSHALL # 清空所有数据
FLUSHDB # 清空当前数据库
11.2.2 推荐的替代方案
# ✅ 安全替代
# 使用SCAN代替KEYS
SCAN 0 MATCH user:* COUNT 100# 使用UNLINK代替DEL(大键)
UNLINK bigkey# 使用pipeline批量操作
11.2.3 键命名规范
# ✅ 推荐的键命名
user:1001:profile # 用户资料
product:2001:inventory # 商品库存
session:abc123 # 用户会话
cache:user:1001 # 缓存数据# ❌ 不推荐的键命名
u1001 # 太简短,不清晰
user_1001_profile_data # 使用下划线,过长
11.2.4 过期时间设置
# ✅ 合理的过期时间设置
# 会话数据:30分钟
SET session:abc123 "data" EX 1800# 缓存数据:1小时
SET cache:user:1001 "data" EX 3600# 验证码:5分钟
SET captcha:123456 "code" EX 300
11.3 最佳实践总结
-
命令选择:
- 优先使用时间复杂度低的命令
- 使用批量操作减少网络往返
- 避免在生产环境使用阻塞命令
-
键设计:
- 采用统一的命名规范
- 使用冒号分隔命名空间
- 避免过长的键名
-
内存管理:
- 合理设置过期时间
- 及时清理无用数据
- 监控内存使用情况
-
安全考虑:
- 设置访问密码
- 限制网络访问
- 禁用危险命令
总结
本文详细介绍了Redis的基础命令操作:
主要内容回顾
- 连接命令:PING、AUTH、SELECT等基础连接操作
- 键操作:EXISTS、DEL、EXPIRE、TTL等通用键管理
- 字符串命令:SET、GET、INCR等字符串和数值操作
- 数据结构命令:Hash、List、Set、ZSet的基本操作
- 服务器命令:INFO、CONFIG等服务器管理命令
- Java集成:Spring Boot中Redis命令的具体实现
- 性能注意事项:命令性能对比和使用建议
关键要点
- 安全使用:避免使用KEYS等阻塞命令,使用SCAN代替
- 性能优化:使用MGET/MSET等批量操作,减少网络开销
- 键设计:采用统一的命名规范,便于管理和维护
- 过期策略:合理设置键的过期时间,避免内存浪费
- 原子操作:使用Lua脚本保证复杂操作的原子性
实战建议
- 熟练掌握基础命令,理解每个命令的适用场景
- 结合Java代码实践,掌握在应用中的具体使用
- 关注性能影响,选择合适的命令和操作方式
- 建立良好习惯,遵循命名规范和最佳实践
- 持续学习,深入理解Redis的数据结构和实现原理
通过本文的学习,你应该能够熟练使用Redis的基础命令,为后续深入学习Redis的高级特性打下坚实基础。
下一篇预告:《Redis字符串(String):最常用的数据结构,这些用法你都懂吗?》