Redis基础指令以及简单集群思想篇

 

# 1、启动Redis服务器:

```java
cd redis-5.0.5/src
./redis-server
```

# 2、启动Redis客户端 ```java
cd redis-5.0.5/src ./redis-cli ping(查看是否正常开启,正常返回pong) //以下指令均是在客户端进行 ```
# 3、set命令添加或覆盖一个字符串或数字类型 ```java set key value:(设置单个值的方式) 127.0.0.1:6379> set platform:info "字符串" //获取值 127.0.0.1:6379> get platform:info mget获取多个值: 127.0.0.1:6379> mget platform:version platform:info ```
# 4、对于数字类型的字符串,有以下操作可以进行算术操作: ```java DECR/INCR:数字类型数据自减和自增 DECRBY/INCRBY:数字类型数据减去某个指定的整数或者增加一个指定的整数 INCRBYFLOAT:数字增加一个浮点数,负数表示减去 例如: 127.0.0.1:6379> set platform:version 1 127.0.0.1:6379> incrby platform:version 2 ```
# 5、key指令查询Redis中所有的key ```java 127.0.0.1:6379> keys platform:* ``` key后面可以用“*”或者“?”: - Platform:*,匹配"platform:" 开头的Key; - pl?tform,匹配platform或者pletform; - *,查询所有的keys;

# 6、exists判断key是否存在 ```java 127.0.0.1:6379> exists platform:info ```
返回1表示存在,0表示不存在
# 7、del命令删除Key-Value ```java 127.0.0.1:6379> del platform:info ``` 返回1表示删除成功,0表示失败 设定删除的时间,然后自动删除: ```java 127.0.0.1:6379> expire platform 10 //ttl命令查看Key的存活时间 127.0.0.1:6379> ttl platform ```
# 8、Redis List(适合大数据量,要求插入速度极快的场景) ## 8.1、rpush,lpush,lrange rpush将多个值放入list尾部,lpush则将多个值放在list头部,lrange能从左到右的心事指定范围的列表 ```java 127.0.0.1:6379> rpush platform:history "字符串" "字符串" 127.0.0.1:6379> lpush platform:history "字符串" 127.0.0.1:6379> lrange platform:history 0 2(表示从0到2的范围) ```
## 8.2、rpop和lpop rpop可以从列表尾部取出一个元素,lpop则会从列表的头部取出一个元素,llen可以返回List的长度 ```java 127.0.0.1:6379> rpop platform:history 127.0.0.1:6379> lpop platform:history 127.0.0.1:6379> llen platform:history ``` 另一种取值的方式是Redis提供的带阻塞的pop命令,blpop或者brpop,这两个指令会在List为空的时候处于等待状态,直到列表有元素: ```java 127.0.0.1:6379> blpop platform:history 0 响应的返回值: 1)"platform:history" 2)"字符串" //语句中的0表示永久等待 返回值中有Key值(级名称),第二个为元素值; ```
# 9、Redis Hash - hset key field value,给指定的Key设置一个字段值,若值已存在,则覆盖,返回0表示失败,1表示成功; - hget key field,获取指定Key的field字段的值,若不存在,返回nil; - hexists key field,判断指定的Key的field字段是否存在,返回1表示存在,0表示不存在; - hkeys key,返回Key所指定的hash所有的字段名; - hgetall key,返回所有的字段名和字段值; - hdel key field[field],删除多个字段; ```java //现在假设系统的用户session会话保存到Redis中,Key值保存的格式为session:{sessionId},一下的sessionId假设为"1xac": 127.0.0.1:6379>hset session:1xac name good (integer) 1 127.0.0.1:6379>hset session:1xac ip 127.0.0.1 (integer) 1 127.0.0.1:6379>hget session:1xac name "good" 127.0.0.1:6379>hkeys session:1xac 1)"name" 2)"ip" 127.0.0.1:6379>hgetall session:1xac 1)"name" 2)"good" 3)"ip" 4)"127.0.0.1" ``` Hash的字段支持递增计算: - hincby key field value,对Key指定的Hash数据中的field的值进行计算,增加整型value; - hincbyfloat key field value,对Key指定的Hash数据中的field的值进行计算,增加浮点数value; ```java 127.0.0.1:6379> hset website access 0 127.0.0.1:6379> hincrby website access 1 127.0.0.1:6379> hget website access ```
# 10、Set Redis的Set除了元素的添加删除操作,还包含集合的并集,交集等,可用于统计访问网站所有的IP,或者统计网站作者共同的粉丝等应用,常见指令: ```java //添加元素 sadd key member[member..] //删除元素 srem key member[member..] //返回集合中的所有元素 smembers key //返回两个集合共同的元素,key1和key2分别代表两个集合 sinter key1 key2 //将key2,key3的交集放到key1中 sinterstore key1 key2 key3 //返回一个合并后的集合 sunion key1 key2 //将key2,key3的并集放到key1中 sunionstore key1 key2 key3 ``` 当Set用于统计网站访问IP的时候,实例如下: ```java 127.0.0.1:6379> sadd ip 192.168.0.1 (integer) 1 127.0.0.1:6379> sadd ip 192.168.0.2 (integer) 1 127.0.0.1:6379> sadd ip 192.168.0.1 (integer) 0 127.0.0.1:6379> smembers ip 1) "192.168.0.2" 2) "192.168.0.1" ``` Set用于查看两人共同好友,示例如下: ```java 127.0.0.1:6379> sadd friends:guo xiaoming kobe (integer) 2 127.0.0.1:6379> sadd friends:gu kobe lbj (integer) 2 127.0.0.1:6379> sinterstore friends:guo-gu friends:guo friends:gu (integer) 1 127.0.0.1:6379> smembers friends:guo-gu 1) "kobe" ```
# 11、Zset 在set基础上增加一个排序的功能,多了一个字段来标识位置 ```shell 127.0.0.1:6379> ZADD mykey 1 one (integer) 1 127.0.0.1:6379> ZADD mykey 2 two 3 three (integer) 2 127.0.0.1:6379> ZRANGE mykey 0 -1 1) "one" 2) "two" 3) "three" ####################################################### 127.0.0.1:6379> ZRANGEBYSCORE mykey -inf +inf #-inf负无穷的含义,及升序排序 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> ZREVRANGE mykey 0 -1 # 降序排序 1) "three" 2) "two" 3) "one" 127.0.0.1:6379> ZRANGEBYSCORE mykey -inf +inf withscores # 同时输出对应的value 1) "one" 2) "1" 3) "two" 4) "2" 5) "three" 6) "3" 127.0.0.1:6379> ZCARD mykey # 获取有序集合中的个数 (integer) 3 ```
# 12、Pub/Sub Redis提供了简单的消息服务,支持publish/subscribe.客户端可以订阅一个或多个频道(Channel),该行为称为subscribe,其他客户端向这些Channel发送消息,称为publish,订阅这些频道的客户端能接收到这些信息;publish/subscribe模式在SpringBoot中可以应用于事件通知,如配置文件更新,缓存更新等; ```java //subscribe订阅频道 127.0.0.1:6379> subscribe news Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "news" 3) (integer) 1 ``` subscribe命令会返回一个数组结构数据,第一行固定的“subscribe”字符串,第二行为订阅号频道的名字,第三行为数字,表示频道总共有多少个订阅者;redis-cli使用了subscribe,将一直等待频道的消息并输出到屏幕,需要重新打开一个终端来执行publish消息,如下: ```java root@lakers1:~# cd redis-5.0.5/src root@lakers1:~/redis-5.0.5/src# ./redis-cli 127.0.0.1:6379> publish news "hello" (integer) 1 127.0.0.1:6379> publish news "world" (integer) 1 ``` 在订阅者的终端上就将看到: ```java 127.0.0.1:6379> subscribe news Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "news" 3) (integer) 1 1) "message" 2) "news" 3) "hello" 1) "message" 2) "news" 3) "world" ``` Redis还提供了订阅指定的模式,使用psubscribe命令: ```java 127.0.0.1:6379> psubscribe news.* ``` 支持的模式如下: - news.* 所有news.开头的频道; - news-? 订阅news-1、news-2频道; - news[123] 订阅news-1、news-2、news-3频道;

# 12、String ```shell 127.0.0.1:6379> get view "0" 127.0.0.1:6379> incr view # 自动++ (integer) 1 127.0.0.1:6379> APPEND view "12" # 字符拼接 (integer) 3 127.0.0.1:6379> get view "112" 127.0.0.1:6379> STRLEN view # 字符长度 (integer) 3 127.0.0.1:6379> INCR view (integer) 113 127.0.0.1:6379> INCRBY view 2 # 增加 2 (integer) 115 127.0.0.1:6379> DECR view # 自减 -1 (integer) 114 127.0.0.1:6379> DECRBY view 2 # 减少 2 (integer) 112 127.0.0.1:6379> GETRANGE view 0 1 # 截取某个字符串 "11" 127.0.0.1:6379> GETRANGE view 0 -1 # 获取整个字符串 "112" 127.0.0.1:6379> SETRANGE view 0 2 # 替换指定位置开始的字符串 (integer) 3 127.0.0.1:6379> get view "212" 127.0.0.1:6379> setex key 30 "hello" OK 127.0.0.1:6379> ttl key (integer) 26 127.0.0.1:6379> get key "hello" 127.0.0.1:6379> ttl key (integer) -2 127.0.0.1:6379> setnx view 0 # 不存在该key则设置,成功返回1,失败返回0 (integer) 0 ###################################################### 127.0.0.1:6379> msetnx k1 v1 k2 v2 (integer) 1 127.0.0.1:6379> mget k1 k2 1) "v1" 2) "v2" 127.0.0.1:6379> msetnx k1 v1 k3 v3 (integer) 0 127.0.0.1:6379> mget k3 # 说明msetnx是一个原子操作,要么都成功,要么都失败 1) (nil) ####################################################### # 对象 127.0.0.1:6379> mset user:1:name gp user:1:age 21 OK 127.0.0.1:6379> mget user:1:name user:1:age 1) "gp" 2) "21" ```
# 13、Geospatial地理位置 ```shell 27.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing (integer) 1 # 添加地理位置 127.0.0.1:6379> GEOADD china:city 112.40 31.90 shanghai (integer) 1 127.0.0.1:6379> GEOPOS china:city beijing shanghai # 获取城市的经纬度 1) 1) "116.39999896287918091" 2) "39.90000009167092543" 2) 1) "112.39999920129776001" 2) "31.89999934908474444" 127.0.0.1:6379> GEODIST china:city beijing shanghai km "959.7309" # 获取两座城市的距离,已km为单位 127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km 1) "shanghai" # 以给定的经纬度为中心,找出某一半径内的元素 127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km withcoord 1) 1) "shanghai" 2) 1) "112.39999920129776001" 2) "31.89999934908474444" 2) 1) "beijing" 2) 1) "116.39999896287918091" 2) "39.90000009167092543" 127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km withcoord count 1 # 限制查找的人数 1) 1) "shanghai" 2) 1) "112.39999920129776001" 2) "31.89999934908474444" 127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km # 以某个元素为坐标,寻找附近的城市 1) "beijing" 2) "shanghai" # Geospatial底层是由ZSET实现的 127.0.0.1:6379> ZRANGE china:city 0 -1 1) "shanghai" 2) "beijing" ```
# 14、Hyperloglog **基数的概念:** 基数(一个集合不重复的元素个数);例如 A{1,3,5,7,7,8} 则基数 = 5 **优点:** 占用内存是固定的,2^64不同的元素的基数,只需要费12KB内存。 ```shell 127.0.0.1:6379> PFADD team lakers sun rocket (integer) 1 127.0.0.1:6379> PFCOUNT team (integer) 3 127.0.0.1:6379> PFADD team2 clipper (integer) 1 127.0.0.1:6379> PFADD team2 net (integer) 1 127.0.0.1:6379> PFCOUNT team2 (integer) 2 127.0.0.1:6379> PFMERGE mergeTeam team team2 OK 127.0.0.1:6379> PFCOUNT mergeTeam (integer) 5 ```
# 15、Bitmaps Bitmaps位图,都是操作二进制位来进行记录,就只有0和1两种状态 ```shell 127.0.0.1:6379> SETBIT sign 0 0 (integer) 0 127.0.0.1:6379> SETBIT sign 1 0 (integer) 0 127.0.0.1:6379> SETBIT sign 2 1 (integer) 0 127.0.0.1:6379> SETBIT sign 3 0 (integer) 0 # 以上记录可以用于表示某个用户的打卡情况等等 127.0.0.1:6379> GETBIT sign 0 # 获取某一天的打卡情况 (integer) 0 127.0.0.1:6379> GETBIT sign 2 (integer) 1 127.0.0.1:6379> BITCOUNT sign # 统计情况 (integer) 1 ```
# 16、设置密码 ```java 127.0.0.1:6379> config set requirepass 123456 OK 127.0.0.1:6379> config get requirepass (error) NOAUTH Authentication required. 127.0.0.1:6379> auth 123456 OK 127.0.0.1:6379> config get requirepass 1) "requirepass" 2) "123456" ```
# 17、SpringBoot集成Redis ```java //配置application.properties spring.redis.host=127.0.0.1 spring.redis.password=123456 spring.redis.port=6379 #最大连接数(0表示无限制 spring.redis.pool.max-active=8 ``` 测试集成是否成功: ```java @Controller @RequestMapping("/strredis") public class RedisStringController { @Autowired private StringRedisTemplate redisClient; @RequestMapping("/setget.html") public @ResponseBody String env(String para) { redisClient.opsForValue().set("testenv",para); String str = redisClient.opsForValue().get("testenv"); return str; } } ``` 上述代码相当于Redis的set和get操作: ```java 127.0.0.1:6379> set testenv 123 OK 127.0.0.1:6379> keys te* 1) "testenv" 127.0.0.1:6379> get testenv "123" ```
# 18、事务篇 ```java //开启事务 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> get k2 QUEUED 127.0.0.1:6379> set k4 v4 QUEUED //结束事务 127.0.0.1:6379> EXEC 1) OK 2) OK 3) "v2" 4) OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set k2 v3 QUEUED //终端事务 127.0.0.1:6379> DISCARD OK 127.0.0.1:6379> get k2 "v2" ```
# 19、主从复制 ## 19.1、一主二仆 为了防止配置错误,先拷贝三份redis.conf,在进行改动配置 ```java root@lakers1:~# cd redis-5.0.5/ root@lakers1:~# cp redis.conf redis6379.conf root@lakers1:~/redis-5.0.5 cp redis.conf redis6380.conf root@lakers1:~/redis-5.0.5 cp redis.conf redis6381.conf //直接进入redis6379.conf(redis6380.conf,redis6381.conf)对下面的三个参数进行修改 root@lakers1:~/redis-5.0.5 vim redis6379.conf logfile "6379.log" dbfilename dump_6379.rdb daemonize yes root@lakers1:~/redis-5.0.5 vim redis6380.conf pidfile /var/run/redis_6380.pid port 6380 logfile "6380.log" daemonize yes dbfilename dump_6380.rdb pidfile /var/run/redis_6380.pid root@lakers1:~/redis-5.0.5 vim redis6381.conf port 6381 pidfile /var/run/redis_6381.pid logfile "6381.log" daemonize yes dbfilename dump_6381.rdb pidfile /var/run/redis_6381.pid ``` ```java /*在同一台虚拟机上模拟多台机器(也可以使用多台虚拟机)*/ //首先开辟三个窗口,分别进入redis的src目录,启动redis的服务(下面为个人的目录) root@lakers1:~# cd redis-5.0.5/src root@lakers1:~/redis-5.0.5/src# ./redis-server ../redis6379.conf root@lakers1:~/redis-5.0.5/src# ./redis-cli -p 6379 127.0.0.1:6379> ping PONG //另外两个窗口也进行相似的操作,如下: root@lakers1:~# cd redis-5.0.5/src root@lakers1:~/redis-5.0.5/src# ./redis-server ../redis6380.conf root@lakers1:~/redis-5.0.5/src# ./redis-cli -p 6380 127.0.0.1:6380> ping PONG --------------------------------------------------------------------------------------------------- root@lakers1:~# cd redis-5.0.5/src root@lakers1:~/redis-5.0.5/src# ./redis-server ../redis6381.conf root@lakers1:~/redis-5.0.5/src# ./redis-cli -p 6381 127.0.0.1:6381> ping PONG /*将6380和6381的两个端口作为从机,6379作为主机,分别在6380和6381窗口执行一下命令*/ 127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 OK 127.0.0.1:6380> info replication # Replication role:slave//此处已经表现出从机的性质 master_host:127.0.0.1 master_port:6379 master_link_status:up//此处正常应该为up,若为down,可能是防火墙没开放该端口 master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:0 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:e009a04f186981bce5897ce60dda671a9201f40a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:0 --------------------------------------------------------------------------------------------------- /*在主机端口执行相关操作*/ 127.0.0.1:6379> set k2 888 OK /*从机端口执行以下操作*/ 127.0.0.1:6380> get k2 "888"//表明主从复制成功 ``` 当主机宕机后,重新开启,两个从机会继续和主机形成一主二仆的关系; 而当从机宕机后重新启动,需重新连接主机,及执行slaveof 127.0.0.1 6379才能成为从机
## 19.2、薪火相传 相当于接力续传,前一个slave可以作为后一个的master 示例如下: ```java //在6381端口执行一下语句 127.0.0.1:6381> SLAVEOF 127.0.0.1 6380 OK --------------------------------------------------------------------------------------------------- //此时主机6379状态如下 127.0.0.1:6379> info replication # Replication role:master connected_slaves:1//连接数剩下1 slave0:ip=127.0.0.1,port=6380,state=online,offset=3385,lag=1 master_replid:e009a04f186981bce5897ce60dda671a9201f40a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3385 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:3385 --------------------------------------------------------------------------------------------------- //6380端口的状态 127.0.0.1:6380> info replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_repl_offset:3413 slave_priority:100 slave_read_only:1 connected_slaves:1//连接的从机数量为1 slave0:ip=127.0.0.1,port=6381,state=online,offset=3413,lag=0 master_replid:e009a04f186981bce5897ce60dda671a9201f40a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3413 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:3413 --------------------------------------------------------------------------------------------------- 127.0.0.1:6379> set k9 v9 OK 127.0.0.1:6380> get k9 "v9" 127.0.0.1:6381> get k9 "v9" /*数据从6379------>6380------>6381*/ ```
## 19.3、反客为主 ```java //让6381重新成为6379的从机 127.0.0.1:6381> SLAVEOF 127.0.0.1 6379 OK --------------------------------------------------------------------------------------------------- //模拟主机宕机 127.0.0.1:6379> SHUTDOWN not connected> exit root@lakers1:~/redis-5.0.5/src# --------------------------------------------------------------------------------------------------- //在6380执行的操作 127.0.0.1:6380> info replication # Replication role:slave//此时6380仍为从机,等待主机的恢复 master_host:127.0.0.1 master_port:6379 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:4394 master_link_down_since_seconds:23 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:e009a04f186981bce5897ce60dda671a9201f40a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:4394 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:4394 //直接成为主机 127.0.0.1:6380> SLAVEOF no one OK 127.0.0.1:6380> info replication # Replication role:master//状态已经改为master connected_slaves:0 master_replid:79701d5bdca81c37afce59649b308cca652153b5 master_replid2:e009a04f186981bce5897ce60dda671a9201f40a master_repl_offset:4394 second_repl_offset:4395 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:4394 --------------------------------------------------------------------------------------------------- //6381端口更换主人 127.0.0.1:6381> SLAVEOF 127.0.0.1 6380 OK ```
## 19.4、哨兵模式 哨兵模式相当于自动的反客为主,能后台监控主机是否故障,如果故障根据投票数自动将从库转换为主库。 哨兵模式实现: 目前是一主二从的状态,配置步骤: 配置哨兵配置文件sentinel.conf并开启哨兵模式 ```shell # sentinel monitor 被监控的名称 host port 1 sentinel monitor myredis 127.0.0.1 6379 1 # 开启哨兵模式 [root@izuf651uvti0zfpng91vp5z src]# ./redis-sentinel ../sentinel.conf ``` 优点: 1、哨兵集群,基于主从复制模式,所有的主从配置优点都有; 2、主从切换,故障可以自动转移,系统的可用性更好; 缺点: 1、不好在线扩容,集群容量一旦达到上限,扩容将比较麻烦;
posted @ 2020-08-01 00:21  AllForward  阅读(45)  评论(0)    收藏  举报