String 的常用的命令
!!!只因redis 命令没有掌握熟练造成400W的损失
为什么会发生以上的生产事故呢?
Redis 当下最火的缓存数据库、而工作中项目中倒是加了redis缓存中间件,感觉挺高大上的,其实呢现实情况下就是在项目中用到了对String 的set、 get 这样的入门级的都算不上的命令,但是如果这样的话数据不发生变化的那我们用map不行么?map不能代替redis数据存储的功能么?
其实redis是一个非常强大并且功能很多的一个缓存中间件,他不仅仅支持那5个基本类型还有3种特殊的基本类型。还有发布、订阅,事务,数据持久化 等等高级功能,而且在分布式的项目中可以用来做分布式锁,还有异步队列、延时队列 等等各种高级功能。如果这些你都知道话还发发生以上的生产事故么?
面试中常问的问题
1、Redis的内存用完了会发生什么?
2、Redis如何做内存优化?
3、Redis为什么需要把所有的数据放在内存中
4、Redis回收进程如何工作的?
5、过期键的删除策略及回收策略
6、海量并发落到一个redis key怎么解决
7、Redis是单进程单线程的?
8、说说Redis哈希槽的概念?
9、怎么理解Redis事务?
10、一个字符串类型的值能存储最大容量是多少?
11、缓存雪崩、击穿、穿透、预防解决方案
12、Redis缓存与数据库一致性问题
13、redis集群的原理是什么
14、Redis集群方案什么情况下会导致整个集群不可用?
15、Redis集群会有写操作丢失吗?为什么?
…
一、基本命令
1、获取当前库的所有的key信息
127.0.0.1:16379> keys *
(empty list or set)
2、 设置一个key为name值为zhangsan 与 key为age值为23
127.0.0.1:16379> set name zhangsan
OK
127.0.0.1:16379> set age 23
OK
3、获取key为name的值
127.0.0.1:16379> get name
"zhangsan"
4、获取当前库的所有的key信息(当前库中已经有两个值了)
127.0.0.1:16379> keys *
1) "age"
2) "name"
5、key为name的值是否存在
127.0.0.1:16379> EXISTS name
(integer) 1
二、String 操作进阶
1、选择index 为 1 的数据库
127.0.0.1:16379> select 1
OK
2、获取当前1库的所有的key信息
127.0.0.1:16379[1]> keys *
(empty list or set)
3、选择index 为 0 的数据库
127.0.0.1:16379[1]> select 0
OK
4、获取当前0库的所有的key信息
127.0.0.1:16379> keys *
1) "age"
2) "name"
5、给定key为name的值设置过期时间
127.0.0.1:16379> EXPIRE name 5
(integer) 1
## 查看key为name的值还有多久过期(-2已经被删除了)
127.0.0.1:16379> ttl name ##
(integer) -2
6、再次查看当前库中的key值此时name 已经被删除了
127.0.0.1:16379> keys *
1) "age"
127.0.0.1:16379> get name
(nil)
三、String 操作高阶
1、选择index 为 1 的数据库
127.0.0.1:16379> select 1
OK
2、获取index 为1的库中key为age的值
127.0.0.1:16379[1]> get age
(nil)
3、将当前库中的key为age的值移动到index为1的库中
127.0.0.1:16379> move age 1
(integer) 1
## 获取当前库中key为age的值,此时没有了
127.0.0.1:16379> get age
(nil)
## 选择index 为 1 的数据库
127.0.0.1:16379> select 1
OK
## 获取index 为1的库中key为age的值(此时已经有值了)
127.0.0.1:16379[1]> get age
"23"
127.0.0.1:16379[1]> keys *
1) "age"
4、 在key为age的值后面追加 …
127.0.0.1:16379[1]> append age ...
(integer) 5
## 获取修改过的值此时已经为 23...
127.0.0.1:16379[1]> get age
"23..."
5、获取当前key为age的值的长度
127.0.0.1:16379[1]> strlen age
(integer) 5
6、数字类型的自增操作
127.0.0.1:16379[1]> set index 0
OK
## 获取当前key为index的值
127.0.0.1:16379[1]> get index
"0"
## 当前key为index的值自增
127.0.0.1:16379[1]> incr index
(integer) 1
127.0.0.1:16379[1]> incr index
(integer) 2
## 当前key为index的值自减
127.0.0.1:16379[1]> decr index
(integer) 1
127.0.0.1:16379[1]> get index
"1"
7、指定值自增自减多少的操作
## 当前key为index的值指定值(20)自增
127.0.0.1:16379[1]> incrby index 20
(integer) 21
127.0.0.1:16379[1]> get index
"21"
## 当前key为index的值指定值(20)自减
127.0.0.1:16379[1]> decrby index 5
(integer) 16
127.0.0.1:16379[1]> get index
"16"
8、字符串区间取值
127.0.0.1:16379[1]> GETRANGE age 0 3
"23.."
## 获取整个字符串的值
127.0.0.1:16379[1]> GETRANGE age 0 -1
"23..."
## 在字符指定位置插入并覆盖相同位置的值
127.0.0.1:16379[1]> SETRANGE age 1 55
(integer) 5
127.0.0.1:16379[1]> get age
"255.."
四、String 操作终极
1、设置key的值并且设置该值的过期时间
## 设置key为name值为张三并设置过期时间
127.0.0.1:16379[1]> SETEX name 20 zhangsan
OK
127.0.0.1:16379[1]> get name
"zhangsan"
2、如果该key不存在的话则设定,存在的话则不设定
## 如果没有key等于name2的时候,设置name2的值
127.0.0.1:16379[1]> SETNX name2 123
(integer) 1
127.0.0.1:16379[1]> get name2
"123"
127.0.0.1:16379[1]> keys *
1) "age"
2) "name2"
3) "index"
## 此时已经有key等于name2的时候,所以设置name2的值失败了
127.0.0.1:16379[1]> SETNX name2 456
(integer) 0
127.0.0.1:16379[1]> keys *
1) "age"
2) "name2"
3) "index"
3、 批量设置值
127.0.0.1:16379[1]> MSET k1 v1 k2 v2 k3 v3 k4 v4
OK
127.0.0.1:16379[1]> keys *
1) "age"
2) "k1"
3) "k3"
4) "k4"
5) "index"
6) "name2"
7) "k2"
4、批量获取值
127.0.0.1:16379[1]> MGET k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
5、 如果不存在的key则创建但是k1已经存在了所以创建失败了,即有一个失败即全失败(原子性事务操作)
127.0.0.1:16379[1]> MSETNX k1 v1 k4 v4
(integer) 0
6、key的巧妙设计:user:{id}:{field},redis 可以这么设计【后续的hash操作比这个要好用】
127.0.0.1:16379[1]> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:16379[1]> mget user:1:name user:1:age
1) "zhangsan"
2) "2"
7、getset命令 先get再set 如果不存在返回nil
127.0.0.1:16379[1]> getset user lisi
(nil)
127.0.0.1:16379[1]> get user
"lisi"
## 如果存在值,获取原来的值并设置新的值
127.0.0.1:16379[1]> getset user zhangsan
"lisi"
127.0.0.1:16379[1]> get user
"zhangsan"
创作不易关注三连击,我会一直持续输出… 期待下一期的多线程的学习 谢谢!
与君共勉 …