前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、Redis启动和连接

1.1、服务端启动

redis-server ../redis.conf

1.2、客户端启动

也就是说可以远程连接其他的redis,-p 默认是6379 -h 默认是 127.0.0.1,密码登录 -a 12345

redis-cli -p
redis-cli -p 6379 -h 127.0.0.1
redis-cli -p 6379 -h 127.0.0.1 -a 123456

1.3、停止redis服务

redis-cli  shutdown nosave|save 是否生成持久化文件

2、Redis特性

1、速度快

  1.1、redis的所有数据都是存在在内存中的,Redis使用C语言实现的,C语言距离操作系统更近,因此速度回相对较快

  1.2、Redis使用了单线程,预防了多线程可能产生的竞争问题

2、基于键值对的数据结构服务器

3、客户端语言多,有Java PHP C C++等

4、持久化:通常情况下降数据放到内存中是不持久的,一旦发送断点或者故障就完犊子了,因此有两种持久化方式RDBAOP,这个持久化方式,后面解释喽

5、主从复制:Redis提供了复制功能,实现类多个相同数据的Redis脚本

6、高可用和分布式:高可用,Reidis Sentinel 哨兵,他能保证Redis节点的故障发现和故障自动转移,Redis从3.0版本正式出了分布式Redis Cluster,它是Redis真正的分布式实现。提供了高可用、读写和容量的扩展性

单线程为什么这么牛

1、纯内存访问:Redis将数据放到内存中,内存相应时间相当快

2、非阻塞I/O :i/o多路复用技术的实现

3、单线程,避免了多线程的切换和资源的竞争,但是单线程会有一个问题,那就是每个命令的执行时间是有要求的,如果某个命令执行时间过长,就会造成其他的命令的阻塞,对于redis这种来说是非常致命的。

3、常用命令

命令 说明 解释
keys * 查看当前库的所有数据  
dbsize 查看当前库有几个数据  
flushdb 将当前库数据清除  
flushall 清除所有库的信息  
select 0、1、...15 移动仓库(一共16个)  
move keyName 2 将数据移动到其他库中,例如3库  
     
type keyName 查看数据类型  
object encoding keyName 查看内存编码  
     
ttl keyName 查看过期时间 -1永不过期
-2已经过期
expire keyName 10 设置k1过期时间,为10秒  
persist keyName 将过期时间清除,永不过期  
exists keyName 看看是否存在keyName  

4、键管理

4.1、重命名

重命名期间会删除旧的key,然后再赋值,如果键的值比较大,会存在阻塞Redis的可能性,这点千万不能忽视

如果healer也是一个存在的key,那么就会覆盖掉healer以前的值,为了防止被强行rename redis提供了renamenex,确保只有 newkey不存在时候才覆盖

rename healejrean healer

4.2、键过期

1、设置键的过期时间

expire hello 10 10秒过期
expireat hello 1512552122 时间戳秒过期


pexpire hello  毫秒过期
pexpireat hell 时间戳毫秒过期

2、将过期时间清除

persist hello  

4.3、迁移键

有的时候我们需要将一个redis迁移到两一个redis。redis提供了几种方法,但是使用场景有所区别

命令 作用域 原子性 支持多个键
move redis实例内部的库
dump + restore redis实例之间
migrate redis实例之间

4.3.1、move

只用于在Redis内部进行数据迁移,Redis内部可以邮多个数据库,但是在数据上不是共通的

move key db

4.3.2、dump+restore

实现在不同的redis实例之间进行数据迁移的功能,只要分为两步

1> 在源redis上dump命令将键值序列化,格式采用的是RDB格式,

2> 在目标Redis奖上面的序列化的值进行复原,其中ttl参数表示过期时间 ttl=0表示没有过期时间

原理探究:这个过程不是原子性质的,而是在通过两个客户端完成的的,一个dump,一个restore

dump key value
restore key ttl value

4.3.3、migrate (移动)

这个是相当于是进行了3个命令 dump+restore+del 这个是原子性的

目标redisip,端口,key、目标的索引库、迁移的超时时间

127.0.0.1:6380>migrate 127.0.0.1 6379 hello 0 1000 

迁移多个key
127.0.0.1:6380>migrate   127.0.0.1 6379 "" 0 5000 keys key1 key2 

4.4、键遍历

redis提供了两个命令遍历所有的键分别是keys scan

4.4.1、全量遍历键

4.4.1.1、匹配遍历

*匹配任意字符 
keys * 

 ?匹配一个字符
127.0.0.1:6379>keys h?ll*
hello

* [] 匹配部分字符 [1,3] 匹配1或者3 [1-10] 匹配1到10之间的任意数字
keys *

4.4.1.2、删除我们查找到的相关key

再强调redis是单线程的,如果redis中存在了大量的键就不太美妙了,可能会造成redis阻塞,所以一般不建议在生产环境使用keys命令,但是假如有时候不得不使用怎么办 ,使用scan命令

删除vedio开头的键
keys vedio* | xargs redis-cli del

4.4.2、渐进式遍历

scan cursor [match patten] [count number]

cursor:必须参数,是一个游标,第一次遍历从0开始,每次scan遍历都会返回当前游标的值

match pareetn: 匹配模式,和上面的keys * 匹配模式基本一致

count: 显示多少个,默认是10

下面这个6就是下次遍历的游标
127.0.0.1:6379> scan 0
1) "6"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
    10) "key:7"
    11) "key:1"

127.0.0.1:6379> scan 6
1) "11"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

127.0.0.1:6379> scan 11
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"

4.4.2.1、其他数据类型的渐进式遍历

比如哈希类型,集合类型,有序集合 hgetall smembers zrange 对应的命令是hscan sscan zscan

注意:游标式遍历相当于是分布执行命令,如果中间有添加数据,新增的键可能没有便利到,这个是开发时候,需要考虑的

String key ="myset"
String patten="old:user*";
String cursor = "0";
while(true){
	ScanResult scanResult = redis.sscan(key,cursor,patten)
	List emelemts = scanResult.getResult();
	redis.srem(key,elements);
	
	//获取新的游标
	cursor =scanResult.getStringCursor();
	if("0".equals(cursor)){
		break; /、结束循环
	}
}

5.5、数据库管理

redis具有16个数据库,正常情况下我们使用的只是0号数据库,例如Redis Cluester中只允许使用0号数据库,只不过为了向下兼容老版本的数据库功能,没有废弃掉罢了,那么为什么要废弃它呢

答案:

1、redis是单线程的,如果使用这些数据库,那么还是使用的同一个cpu,相互之间会有影响,如果分配不同的任务,加入有一个数据库太慢,那么其他的任务就会受到影响

2、完全可以在一台机器上部署多个redis,因为现在计算机都是有多个cpu的,这样保证了业务直接不会受到影响,又合理的利用了资源

ContactAuthor