一、基础知识
- Redis分类
KV、Bson、列族、图形、 - CAP+BASE
- CAP概念:C:强一致性、A:可用性、P:分区容忍性
- CAP中3进2:
对于分区容忍性是我们必须实现的;所以我们只能在一致性和可用性之间进行权衡。AP 大多数网站架构的选择;CP Redis、Mongodb - BASE概念:基本可用、软状态、最终一致性
- ACID
A:原子性、C:一致性、I:独立性、D:持久性 - Redis的特点
Redis支持数据的持久化,持久化到内存、Redis支持丰富的数据类型、Redis支持数据的备份 - Redis是单进程 epoll模型
- Redis默认16个数据库、可以通过select 切换数据库;keys *查看当前数据库key的数量;默认端口6379
二、 Redis数据类型
- String:简单的kv键值
- List
- Set
- Hash:kv模式不变,key不变,value则是键值对组成 eg:key:user value:id:11
- Zset
三、 Redis基本操作命令
-
Key的操作命令:
- key * :查看数据库中的key
- exit k1 :判断某个key是否存在
- move key db :将某一个key移动到db库中
- expire k1 10:为给定的k1设置过期时间10秒
- ttl k1: 查看k1的存活时间-1永不过期 -2表示已过期
- type k1 :查看k1数据类型
-
String操作
- set/get/del/append/strlen:设置/取出/删除/追加
- incr 3:依次增加3
- getrange k1 0 3 :截取字符串
- setex k3 10:设置时间
- mset k1 v1 k2 v2 同时设置多个键值
-
List操作
- lpush :在左边插入
- rpush :右边插入
- lpop : 取出一个
- lrange list01 0 -1 取出list01 中的值
- lindex:获取所在索引
- lrem list01 2 3 :在list01中删除2个3 删除N个value
-
set操作
- sadd set01 v1:添加
- smembers set01: 查看集合的元素
- scard set01 :获取集合中的元素个数
- srem set01 3 :删除集合中的元素
- srandmember set01 3 :在集合set01中随机出3个证书
- spop set01: 随机出栈
- sdiff set01 set02: 取出set01的差集
- sinter set01 set02 :交集
- sunion set01 set02 :并集
-
hash操作
- hset user id 11 :添加
- hget user id :取出记录
- hmset user id 11 name lisi :添加多个
- hgetall user :一次取出user中的所有属性kv
- hdel user name :删除user中的name属性kv
- hexists user name :判断user中name键是否存在
- hkeys user :取出user中所有的key
- hvals user :取出user中所有的value
-
Zset操作
- zadd zset01 60 v1 70 v2:将一个或多个成员元素及其分数值加入到有序集当中
四、阅读Redis配置文件
- tcp-keepalive:通讯状态是否良好;单位是秒,如果设置为0,则不会进行keepalive检测,建议设置成60
- Syslog-enabled:是否把日志输出到Syslog中
- Redis缓存过期策略配置:6种
Volatile-lru: 从已设置过期时间的数据集,挑选最近最少使用的数据淘汰
Allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
Volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allKeys-random: 从数据集(server.db[i].dict)中任意选择数据淘汰
Volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
Noeviction:永不过期(默认) - Redis中文配置文件
五、Redis的持久化
rdb
- 概念: 将内存中的快照写入磁盘
- 过程:Redis会单独创建fork,一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化结束,在用临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何io操作的,这就确保了极高的性能。RDB方式比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失。
- Fork:和当前进程一样的进程,新进程的所有数据都和原进程一致。
- RDB保存为dump.rdb文件;配置文件默认触发条件:1分钟内改变1万次;或5分钟内改变10次;或15分钟内改变1次。
- 使用Save后可以手动触发快照命令
- 如何恢复:启动服务后能自当读取bin下的dump.rdb文件。
aof
- AOF概念:以日志的形式记录每个写操作。保存为appendonly.aof文件
- 配置文件:默认是关闭的则需要修改:appendonly yes
- aof文件损坏时可以使用redis-check-aof --fix进行修复aof文件。
- aof的策略:appendfsync: Always:同步持久化;everysec:每秒中变动进行持久化;No:不进行持久化。
- Rewrite:AOF采用文件追加方式,文件会越来越大,当AOF文件超过某一阙值时,Redis会启动AOF文件内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof
- 重写原理:Redis会记录上次重写时AOF大小,默认配置时当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
- 重写配置文件:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64M - RDB与AOF对比:
AOF优势可以灵活的进行配置,而aof文件会越来越大,会大量频繁的造成IO,效率低于RDB,RBD会丢失数据。 - 同时开启两种持久化方式:在这种情况下,Redis重启时会优先载入AOF文件恢复原始数据,同时使用两者时服务器重启也只会找AOF文件。
六、Redis的事务
-
Redis支持部分事务,不保证原子性,没有事务的回滚。
-
常用命令:multi:开启事务;discard:取消事务;exec:执行事务;unwatch:取消watch命令对所有key的监视;watch key:监视一个key ,如果在事务执行之前这个key被其他命令所改动,那么事务将被打断。
-
全体连坐:如果命令中有错误,即使执行exec命令后也不会进行提交
-
冤头寨主:如果命令没错,而在命令执行过程中出错时,执行exec命令时,没有错的命令能够正常执行,出错的命令则不会保存。
-
乐观锁:每行记录后边加一个版本号Version,先查版本号,然后每次修改提交时再取出版本号与自己刚开始拿到的版本号对比,一致时进行保存。
-
悲观锁:每次拿数据都认为数据被修改,每次都进行表锁。
-
CAS:
-
Watch的使用:(事务被打断)
Watch balance //监控key
Multi //开启事务
.... //一系列操作(如果此key又被另一个人修改则事务会被打断)
exec //执行事务
注:如果在监控期间有人进行了修改数据,则exec执行操作时不会成功的;使用unwatch命令后再次使用watch balance 在进行一系列操作。
- 总结:watch命令类似乐观锁,如果key值被别的进程修改,则整个事务队列不会被执行;
七、Reidis的发布订阅(了解)
- 是进程间的一种消息通信模式:发送者发送消息,订阅者接收消息。
-
原理图理解:
1.消息订阅
2.消息发布 - 命令
- 订阅:subscribe c1 c2 c3
- 发布消息: publish c2 hello
八、Redis的Master-slave(重要)
- 使用:
1 配从不配主
daemonize yes
pidfile /var/run/redis6379.pid //pid文件的名字
port 6379
logfile "6379.log" //log文件的名字
dbfilename dump6379.rdb //dump.rdb的名字
2 链接:slaveof 主机ip地址 主机端口号
每次与master断开之后,都需要重新连接,否则从机在宕机重启后状态变为了master。
查看机器状态:info replication
- 一主二从:A(M)-->B(S) ; A(M)-->C(S)只有Master可以进行写操作,主机宕机后,从机原地待命,从机宕机重启后机器变为Master。
- 薪火相传: A(M)-->B(S)--->C(S)
B机器(192.168.43.80)
slaveof 192.168.43.79 6379
C机器(192.168.43.81)
slaveof 192.168.43.80 6380
- (反客为主)主从切换:主机宕机后从机切换为主机,不再是原地待命。
slaveof no one //重新指定一个Slave机器为Master
- 原理:
- Slave启动成功连接到Master后会发送一个sync命令
- Master接到命令启动后进行存盘,将所有的数据修改指令传送到slave,以完成一次完全同步。
全量复制:而Slave服务在接收到数据文件后,将存盘并加载到内存中。
增量复制:Master继续将新的修改命令传递给Slave完成同步。但是只要重新连接Master,一次完全同步(全量复制)将被自动执行。
- 哨兵模式:一主多从,能够实现自动切换
1 使用:
- 创建sentinel.conf配置文件:
sentinel monitor hist6379 127.0.0 6379 1
其中sentinel monitor 被监控数据库名字 IP 端口号 1 其中1表示主机挂掉后salve投票成为主机。
- 启动哨兵
redis-sentinel /myredis/sentinel.conf
- 缺点:Master向Slave复制时有一定的延迟
九、Java链接Redis--使用连接池处理
使用Jedis连接Redis
Jedis jedis=new Jedis("127.0.0.1",6379);
//Jedis常用API
jedis.set("K1","V1");
Set<String> sets = jedis.keys("*");
System.out.println(sets.size());
//Jedis事务
Transaction transaction = jedis.multi();
transaction.set("", "");//操作
transaction.exec();//提交
//transaction.discard();//放弃提交
事务
public boolean transMethod(){
Jedis jedis=new Jedis("127.0.0.1",6379);
int balance;//可用余额
int debt;//欠额
int amt=10;//实刷额度
jedis.watch("balance");//监控
balance=Integer.parseInt(jedis.get("balance"));
if(amt>balance){
jedis.unwatch();//放弃监控
return false;
}else{
Transaction transaction=jedis.multi();
transaction.decrBy("balance", amt);
transaction.incrBy("debt", amt);
return true;
}
}
主从(理解)
//模拟主从复制
public void testMasterSlave(){
Jedis jedis_Master=new Jedis("127.0.0.1",6379);
Jedis jedis_Slave=new Jedis("127.0.0.1",6380);
jedis_Slave.slaveof("127.0.0.1", 6379);
jedis_Master.set("K1", "V1");
jedis_Slave.get("K1");
}
连接池(常用)
//连接池工具类--单例模式
static class JedisPoolUtil{
private static JedisPool jedisPool=null;
private JedisPoolUtil(){}
//获取单一对象
public static JedisPool getJedisPoolInstance(){
if(jedisPool==null){
synchronized (JedisPoolUtil.class) {
if(jedisPool==null){
//配置文件
JedisPoolConfig poolConfig=new JedisPoolConfig();
poolConfig.setMaxIdle(32);//多少个空闲
poolConfig.setMaxWaitMillis(100*10000);
jedisPool=new JedisPool(poolConfig,"127.0.0.1",6379);
}
}
}
return jedisPool;
}
//释放
@SuppressWarnings("deprecation")
public static void release(JedisPool jedisPool,Jedis jedis){
if(jedis!=null){
jedisPool.returnResourceObject(jedis);
}
}
}
网友评论