单线程来执行redis命令

redis数据类型

类型:String(字符串)
命令:get key、set key value
应用场景:业务方法缓存、值缓存、计数器

类型:List(列表)
命令:lpush listvalue、lrange list 0 -1、lpop list、rpop list
应用场景:先进先出(消息队列)、 后进先出(栈)、链表
注意:lpop/rpop 左出和右出

类型:Set(集合)
命令:add key value、smembers key
场景:交集(共同好友)差集(二度好友)

类别:Hash(字典、Map)
命令:hset key field value、hexists key field、hlen key返回元素个数、del key field、hkeys key获取所有熟悉、hvals key 获取value值
hincrby key field (购物车数量新增)、hsetnx key field 不存在插入
场景:存储用户的信息、购物车(操作购物车对象field值)

类别:Zset
命令:zadd key score value、zrangebyscore key -inf +inf
场景:排行榜、播放量
注意:大部分与set类型相似,多了score排序的功能

类别:geospatial(地理坐标经纬度)
命令:geoadd key longitude latitude member、geopos key member、geodist key memberA memberB 单位(m/km)、georadius key longitude latitude 500 单位(m/km)
georadiusbymenber key member 1000 km
场景:地理经纬度应用,附近地点
注意:通过后台程序导入城市地点的经纬度到redis中、单位 m km mi英里 ft英尺、获取两地的距离、附近的人通过半径查询
geo底层是用zset实现,可以使用zset相关命令操作geo(zrange key 0 -1/zrem key member)

类别:hypelonglong(基数-不重复的元素)
命令:pfadd key valuea valueb valuec、pfcount key、pfadd key2 valuec valued、pfmerge key3 key key2
场景:统计网站HV
注意:set可以实现同样的使用场景,比如统计网站访问用户量,hypelonglong的优势在于占用内存十分少,2^64仅仅使用固定的12KB,存在在错误率0.81%

类别:bitmap(位存储)0 1 0 0
命令:setbit key value 0/1、getbit key value、bitcount key返回1的数量(命令 事件 参数 0/1值)
场景:统计用户信息活跃不活跃,统计用户打卡信息user:userId当做key值、可以节约内存

redis事务操作

事务

事务:一组命令的集合,要么全部成功,要么全部失败;原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability);
redsi单条命令保存原子性,但是事务不保证原子性;
Redis要么执行其中的所有命令,要么什么都不执行;

开启事务: multi
命令入队:set a a /set b b
执行事务/放弃事务:exec/discard 然后恢复正常的连接状态,后续命令不是事务来执行

编译型异常(命令错误,错误之后可以继续写事务中的命令,但是执行的时候不会成功)事务中所有命令不会被执行;
运行时异常(命令没有错误,但是执行后会存在异常,事务存在语法性0/1,incr key key是字符串)其他命令可以正常执行,错误命令抛出异常(对应了事务不保证原子性);

监控

悲观锁:认为什么时候都会出现问题,无论做什么都会加锁;在所有情况下都进行加锁,比较消耗性能,程序执行都存在等待时间;
乐观锁:认为什么时候都不会出现问题,所有不会上锁!更新数据值的时候会去判断一下,在此期间是否有人修改过这个数据?获取version值,更新时候比较version值;decr incr

监控key值:watch/unwatch
单线程:

  1. 6379:0>set a 100
  2. "OK"
  3. 6379:0>watch a
  4. "OK"
  5. 6379:0>multi
  6. "OK"
  7. 6379:0>decrby a 10
  8. "QUEUED"
  9. 6379:0>exec
  10. 1) "90"

多线程:多线程修复值,使用watch可以当做redis的乐观锁操作!两个线程watch值,值有一个version版本值,在事务执行exec的时候,当更新watch的值发现版本version错误(另外一个线程执行了更新),事务会执行失败,所有一个可以看出,使用watch的时候值的版本version是不会动态更新的,所以可以当做乐观锁来使用;使用unwatch放弃监视,重新watch获取值和版本version;
使用场景:乐观锁(秒杀场景)

Jedis

jedis是redis是官方推荐的java链接工具,使用java操作redis的中间件;对比JDBC,还是不太相同;

执行连接:Jedis jedis = new Jedis(ip,port)
命令操作:jedis.ping() 命令将会成方法来执行使用,jedis的方法类型的执行命令相同
断开链接:jedis.close();

jedis事务,如果是watch可以unwatch然后重新watch进行重试;

  1. Transaction multi = jedis.muli();
  2. try{
  3. multi.set("a","a");
  4. multi.set("b","b");
  5. multi.exec();
  6. }catch(Exception e){
  7. mulit.discard();
  8. e.printStackTrace();
  9. }finally {
  10. multi.close();
  11. }

SpringBoot

①springboot操作数据,spring-data jpa jdbc mongdb redis! SpringData 、SpringBoot;

②说明:在springboot2.x之后,jedis被替换成了lettuce;RedisAutoConfiguration RedisConnectionFactory接口实现类在2.x只有LettuceConnectionFactory相关依赖存在(工厂模式)
jedis:采用的直连,多个线程操作的话,是不安全的,如果需要执行多线程操作,需要使用jedis pool连接池;BIO模式
lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据;NIO模式?性能更好

③SpringBoot所有配置类,都有一个自动配置类,比如RedisAutoConfiguration;自动配置类都会绑定一个properties配置文件,RedisProperties;
@ConditionOnMissingBean 判断条件存在不存在加载Bean,RedisTemlate,stringRedisTemplate

  1. @Bean
  2. @ConditionalOnMissingBean(name = "redisTemplate")
  3. public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
  4. //默认的RedisTemplate,没有过多的设置,redis对象都是需要序列化的
  5. //两个泛型都是Object,Object的类型,我们使用需要强制转换><String,String>
  6. RedisTemplate<Object, Object> template = new RedisTemplate<>();
  7. template.setConnectionFactory(redisConnectionFactory);
  8. return template;
  9. }
  10. @Bean
  11. @ConditionalOnMissingBean
  12. public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
  13. //常用,string操作对象
  14. StringRedisTemplate template = new StringRedisTemplate();
  15. template.setConnectionFactory(redisConnectionFactory);
  16. return template;
  17. }

④redisTemplate不同操作类型,还存在常用操作方法和事务方法与类型对象同级
opsForValue操作字符串
opsForList
opsForSet
opsForHash
opsForZSet
opsForGeo
opsForHyperLogLog

⑤连接客户端对象
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();

⑥序列化配置

  1. /*
  2. * 1使用Jackson2JsonRedisSerializer需要指明序列化的类Class,可以使用Obejct.class
  3. * <p/>
  4. * 2使用GenericJacksonRedisSerializer比Jackson2JsonRedisSerializer效率低,占用内存高。
  5. * <p/>
  6. * 3GenericJacksonRedisSerializer反序列化带泛型的数组类会报转换异常,解决办法存储以JSON字符串存储。
  7. * <p/>
  8. * 4GenericJacksonRedisSerializer和Jackson2JsonRedisSerializer都是以JSON格式去存储数据,都可以作为Redis的序列化方式
  9. */
  10. @SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
  11. @SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
  12. @SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
  13. @SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;

Redis.conf配置文件了解

1、开头使用内存大小gb/GB 不区分大小写;
2、include包含多个配置文件,多人开发;
3、loadmodule加载新的模块功能;
4、network网络,bind绑定的IP、port指定的运行端口、timeout设置客户端连接时的超时时间、tcp-keepalive单位是秒,将周期性的使用SO_KEEPALIVE检测客户端是否还处于健康状态,官方建议300s,如果为0则不进行健康检查、protected-mode yes 开启包含模式;

5、通用GENERAL
①daemonize:设置为yes表示指定Redis以守护进程的方式启动(后台启动),默认值为 no;需要开启,防止客户端关闭则结束进程?;
②pidfile:配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面;
③loglevel :订阅日志级别,默认notice(适量日志信息,使用于生产环境)、debug(记录大量日志信息,适用于开发、测试阶段)、verbose(较多日志信息)warning(仅有部分重要、关键信息才会被记录);
debug->verbose->notice->warning 日志级别
④logfile :配置log文件地址,默认打印在命令行终端的窗口上;
⑤databases:设置数据库的数目。默认的数据库是DB 0,可以通过select dbid切换到其他数据库,数据库取值0-15;

6.快照snapshotting(持久化)- redis是内存数据库,如果没有持久化的话,当断点时,redis数据会丢失;
①save:这里是用来配置触发 Redis的持久化条件,也就是什么时候将内存中的数据保存到硬盘
save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存 save;
300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存 save;
60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存;
②stop-writes-on-bgsave-error :默认值为yes,持久化失败是否继续工作;
③rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储,是否开启压缩rdb文件,会消耗CPU资源;
④rdbchecksum :默认值是yes。在保存快照数据rdb文件后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能;
⑤dbfilename :设置快照的文件名,默认是 dump.rdb
⑥dir:rdb文件保存的目录

7.replication复制(主从复制)

8.security安全
Redis入门 - 图1
①requirepass:设置redis连接密码;
②rename-command:命令重命名;禁用危险命令,例如flushdb(rename-command FLUSHALL “”)、flushall、keys,config(客户端连接后可配置服务器)
config set requirepass 123456设置密码 config get requirepas 获取密码

9.clients客户端
Redis入门 - 图2
maxclients :设置客户端最大并发连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件。 描述符数-32(redis server自身会使用一些),如果设置 maxclients为0 。表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

10.memory management内存管理
①maxmemory:设置Redis的最大内存,如果设置为0 。表示不作限制。通常是配合下面介绍的maxmemory-policy参数一起使用;
②maxmemory-policy :当内存使用达到maxmemory设置的最大值时,redis使用的内存清除策略;对比线程满了,java程序做的操作,丢弃等..
LRU:最近使用 Least Recently Used
1)volatile-lru 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used ) ;(内存满了利用LRU算法删除有过期时间的数据)
2)allkeys-lru 利用LRU算法移除任何key(利用LRU算法删除任务key)
3)volatile-random 移除设置过过期时间的随机key(随机删除设置过期key)
4)allkeys-random 移除随机key
5)volatile-ttl 移除即将过期的key(minor TTL)
6)noeviction noeviction 不移除任何key,只是返回一个写错误 ,默认选项
③maxmemory-samples :LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存)

11.addend only mode 仅附加模式(参考拷贝:https://www.cnblogs.com/ysocean/p/9074787.html
①appendonly no 默认关闭,即不开启aof模式,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了;
②appendfilename :aof文件名,默认是”appendonly.aof”持久化默认文件名称
③appendfsync:aof持久化策略的配置;
no 表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快;
always 表示每次写入都执行fsync,以保证数据同步到磁盘;
everysec 表示每秒执行一次fsync,可能会导致丢失这1s数据;
④no-appendfsync-on-rewrite:在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。 设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。默认值为no。
⑤auto-aof-rewrite-percentage:默认值为100。aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。
⑥auto-aof-rewrite-min-size:64mb。设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写。
⑦aof-load-truncated:aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象 redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。默认值为 yes。

12.lua scription LUA脚本

13.redis cluster redis集群

Redsi持久化

RDB(redis database)- 全量持久化 - 主从复制中备份数据

1、手动执行命令save: 阻塞
Redis入门 - 图3
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止;

2、手动执行命令bgsave 非阻塞

Redis入门 - 图4
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求,对比save是非阻塞的,具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,主进程不进行任何的IO操作,在子程序完成后自动结束,同时在fork子进程的时候会有临时的rdb文件,快照持久化完成后替换原来的快照文件。而且阻塞只发生在fork阶段,一般时间很短,基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令;
Redis入门 - 图5
3、自动触发bgsave,通过redis.conf配置文件来执行
#save 900 1 900秒内修改了1次key值,触发rdb操作,持久化数据,生成rdb文件(二进制)
#save 300 10 300秒内修改了10次key值,触发rdb操作,持久化数据,生成rdb文件(二进制)
#save 60 10000 60秒内修改了10000次key值,触发rdb操作,持久化数据,生成rdb文件(二进制)
#save 60 5 60秒内修改了5次key值,触发rdb操作,持久化数据,生成rdb文件(二进制)
stop-writes-on-bgsave-error :默认值为yes,持久化失败是否继续工作;
rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储,是否开启压缩rdb文件,会消耗CPU资源;
rdbchecksum :默认值是yes。在保存快照数据rdb文件后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能;
dbfilename :设置快照的文件名,默认是 dump.rdb
dir:rdb文件保存的目录

触发rdb机制,备份生成dump.rdb文件:
1、满足save规则
2、执行flushall命令
3、退出redis

如果恢复rdb文件,只需要将rdb文件放到我们redis启动目录就可以了,scp拷贝rdb文件到另外一台服务器进行备份;

  1. 6379:0>config get dir
  2. 1) "dir"
  3. 2) "/data" #如果目录存在rdb文件,启动redis的时候,将会将持久化数据,加载到内存中

RDB优势

1、RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复;
2、对数据的完整性要去不高;
缺点:
1、需要一定的时间间隔进程操作,如果redis宕机了最后一次rdb全量备份数据就没了;
2、bgsave的fork进程的时候,会占用一定内存空间;

AOF(append only file)

Redis入门 - 图6
每当有一个写命令(读命令不记录)过来时,就直接保存在我们的AOF文件中,只许追加文件单位不可改写文件,redis启动之初会读取该文件重构数据,换言之,redis重启的话根据日志的内容将写指令从前到后执行一次完成数据的恢复工作;当appendonly.aof文件损坏的时候,redis启动不了,可以使用redsi自带的redis-check-aof —fix进行修复文件

Redis入门 - 图7
AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写;
Redis入门 - 图8
触发机制:
1、每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好; 表示每次写入都执行fsync,以保证数据同步到磁盘;
2、每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失;表示每秒执行一次fsync,可能会导致丢失这1s数据;(自带触发)
3、不同no:从不同步,效率最高;表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快;

①appendonly no
②appendfilename appendonly.aof
③appendfsync:aof持久化策略的配置 no always everysec ;
④no-appendfsync-on-rewrit
⑤auto-aof-rewrite-percentage:默认值为100,aof自动重写配置
⑥auto-aof-rewrite-min-size:64mb 设置允许重写的最小aof文件大小,来解决最小为多少不必重写
⑦aof-load-truncated:默认值为 yes。

AOF优势

1、AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。(2)AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损;
2、AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写;
3、AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据;
缺点:
1、对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大,恢复速度比起rdb慢;
2、AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的;
3、aof数据恢复可能存在BUG,恢复数据和原本不一致;

对比

Redis入门 - 图9
性能建议:
1.通常情况下是两则同时使用,在同时使用的情况,redis启动的话,默认是aof文件来恢复数据,因为aof文件保存了命令,数据更加完整;
2.rdb是作为数据的备份,建议只在slave从库上继续rdb持久化,而且只许15分钟备份一次就够了,只保存save 900 1这条默认命令;
3.如果是使用aof的话,最多会丢失1秒的备份数据,但是会带来磁盘的持续ID写入;
4.如果不使用aof的话,可以节约IO,依靠主从集群来实现高可用,但是如果当主从同时宕机的话,会丢失这段时间的数据,启动脚本恢复需要比较主从rdb文件的最新时间,使用最新一个文件进行数据恢复;

Redis订阅发布

消息发送者、消息消费者、频道
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。(参考复制来源:https://www.runoob.com/redis/redis-pub-sub.html
Redis 客户端可以订阅任意数量的频道。
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
Redis入门 - 图10
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
Redis入门 - 图11

命令

一个客户端通过命令subscribe chat来订阅某一个频道,订阅之后等待接收消息;
另外一个客户端通过命令PUBLISH chat “abb”发送消息到频道上,频道将会将消息发送给订阅的客户端;
退订unsubscribe
Psubscribe 命令订阅一个或多个符合给定模式的频道,PSUBSCRIBE pattern
PUNSUBSCRIBE退订所有给定模式的频道,PUNSUBSCRIB pattern

理解

通过subscribe命令订阅一个频道后,在redis-server里面维护了一个字典,字典的键就是一个个频道,而字典的数据结构是一个链表,链表中保存了所有订阅这个频道chanel的客户端,subscribe命令的关键是将客户端添加到给得chanel的订阅链表中;通过publish命令向订阅者发布消息,redis-server使用给定的频道作为键,在它锁维护的chanel的字典中记录了订阅这个频道的所有客户端的链表,遍历这个链表,将消息发布给所有订阅者;

场景

实时消息系统(在线网站进入到该频道,比如好友邀请消息?)、实时聊天室,公众号订阅推送等(简单使用场景)

Redis主从复制

主从复制,是指一台redis服务器的数据,复制到其他的Redis服务器,前者称为主节点mster/leader,后者称为从节点slave/follower;数据的复制是单向的,只能从主节点到从节点,Masrer以写为主,Slave以从为主。默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点或者没有从节点,但是一个节点只能有一个主节点;同时数据是单向的,只能从主节点到从节点;
作用:
1、数据冗余,主从复制实现了数据的热备份,是持久化之外的一个数据冗余方式;
2、故障恢复,当从节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,实际上是一个服务的冗余;
3、负载均匀,在主从复制的基础上,配合读写分离,可以由节点提供写服务,由节点提供读服务(即写Redis数据时,应用连接主节点,读Redis数据时应用连接从节点),分担服务器压力负载;尤其是在写多读少的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量;
4、高可用(集群)基石:除了以上作用外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础;

redis单节点不安全,因为机子可能出现宕机的情况,出现数据丢失的情况;从结构上来讲,单个redis服务器发生故障,并且一台服务器需要处理所有的请求负责,压力很大,读写请求IO太高,就是可能出现机子宕机,而宕机期间新产生的数据是进不来的,后续也无法进行恢复;从容量上来看,当Redis服务器内存容量有限,就是一台Redis内存容量为256G,也不能将所有内存作为Redis存储内存,一般来说,单个Redis最大使用内存不应该超过20G;
主从复制,读写分离;
Redis入门 - 图12

环境配置(未实操)

只配置从库,不用配置主库!

  1. 6379:0>info replication #查看当前库的信息
  2. # Replication
  3. role:master #角色 master
  4. connected_slaves:0 #没有从机
  5. master_failover_state:no-failover
  6. master_replid:8ba5af588758770c95e8795683e7dbf9e9313ea4
  7. master_replid2:0000000000000000000000000000000000000000
  8. master_repl_offset:0
  9. second_repl_offset:-1
  10. repl_backlog_active:0
  11. repl_backlog_size:1048576
  12. repl_backlog_first_byte_offset:0
  13. repl_backlog_histlen:0

复制三个配置文件,然后修改对应的信息,端口、pid名字(守护进程)、log文件名字、dump.rdb名字;正常情况下,每台redsi启动后都是主节点;

一主二次,从机子通过slaveof 127.0.0.1 6376命令链接主机,真实的主从配置是在配置文件中进行修改,是临时的不是永久的,只有在配置文件中【replication masterip masterport】配置主机的IP和地址;

①主机可以写,从机不能写操作,只能读操作;
②在从机中执行读操作,就会马上提示错误,会提示从机only读操作;
③主机断开链接,从机依旧连接到主机的,但是已经没有读操作了,只有读操作了,当主机重启后,主从依旧可以保存链接;
④从机断开链接后,如果从机与主机的连接方式不是通过配置文件,配置masterIP和端口的话,从机重启之后就是恢复成为master主机,然后重新通过slaveof连接主机之后,(复制原理)将会发起一个sync同步命令,master接收到命令,启动后台进程的存盘,同时2手机所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave从机,并且完成一次完全同步。(全量复制)而slave服务在接收到数据文件数据后,将其他存盘并加载到内存中;(增量复制)Master继续将新的所有收集到的修改命令依次传给slave从机,完成同步,但是只要重新连接master,一次完全同步将被执行,数据将会在从机看到;
Redis入门 - 图13
⑤层层链路的从节点,当主节点master宕机了,在slave-1执行slaveof no one将从机升级为master,其他同级别从机slaceof连接新的主节点;
Redis入门 - 图14

哨兵模式(自动选取主节点)

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。在目录下的redis-sentinel进程;

使得Redis服务器可以跨网络访问 bind 0.0.0.0
# 设置密码 requirepass “123456”
# 指定主服务器,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置 slaveof 192.168.11.128 6379 # 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
masterauth 123456

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器,当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机
Redis入门 - 图15
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。当mster故障宕机时,Redis集群会进行故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。
当主机宕机重启后,是自动连接新的master作为从机使用;

Redis入门 - 图16
Redis安装目录下有一个sentinel.conf文件:
# 禁止保护模式 protected-mode no
# 配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。
sentinel monitor mymaster 192.168.11.128 6379 2
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass sentinel auth-pass mymaster 123456

启动Redis服务器进程 ./redis-server ../redis.conf
# 启动哨兵进程 ./redis-sentinel ../sentinel.conf
首先是主机的Redis服务进程,然后启动从机的服务进程,最后启动3个哨兵的服务进程。

优点

1、哨兵集群,基于主从复制模式,所有的主从配置优点,它都有,负载均匀,故障恢复,高可用;
2、主从可用切换,故障可用转移,系统的可用性很少;
3、哨兵模式是主从复制的升级模式,通过“卫兵”进程来监控集群,手动到自动选取新主节点,更加健壮;
缺点:
1、redis不好在线扩容,集群容量一但达到上限,在线扩容十分麻烦!redis后续3.0很可能新的解决方案,散列槽
2、实现哨兵模式的配置其实很麻烦? .. 哨兵模式的配置?

  1. port 26379
  2. pidfile"/usr/local/redis/var/redis-sentinel.pid"
  3. dir"/usr/local/redis/data/sentinel"
  4. daemonizeyes
  5. protected-mode no
  6. logfile"/usr/local/redis/var/redis-sentinel.log"
  7. sentinel monitor redisMaster 192.168.10.202 6379 2
  8. sentinel down-after-milliseconds redisMaster 10000
  9. sentinel parallel-syncs redisMaster 1
  10. sentinel failover-timeout redisMaster 60000

缓存穿透和雪崩

缓存穿透(需要理解,缩小文字描述)

缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,于是请求都去了持久层数据库,这个会给数据库造成很大压力,这个时候相当于出现了缓存穿透,若黑客利用此漏洞进行攻击可能压垮数据库;查不到;缓存空对象、布隆过滤器(布隆过滤器,在请求到缓存层之前,对请求进行校验,不符合则丢弃,从而避免对底层存储系统的查询压力);

①最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
②如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

缓存击穿(需要理解,缩小文字描述)

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮;
缓存击穿区别缓存穿透区别,是指一个非常热的key值,在不停的当着大并发,大并发对这一个点进行访问,当key在失效的瞬间,有大量并发请求,由于缓存过期了,会同时访问数据库来查询最新数据,并回写缓存,会导致数据库瞬间访问压力过大;量太大,缓存过期;热点数据不过期,使用互斥锁排队,缓存屏蔽

①使用互斥锁(mutex key),简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX不存在则插入或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法;
②热点数据不过期;

雪崩(需要理解,缩小文字描述)

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。缓存预热。缓存缓存本地缓存、互斥锁排队,数据缓存时间随机在一定值范围内部;

Redis入门 - 图17