Redis笔记
安装 解压文件 make下查看是否安装gcc编译工具 修改redis下redis.conf文件 GENERAL daemonize no改为yes 在cd /usr/local/redis目录下 ps -ef|grep redis 查看服务是否启动 进入usr/local/bin下启动服务:redis-server /redis/redis.conf redis-cli -p 6379 ping 说明启动成功 shutdown 关闭服务 进入usr/local/bin下:redis-benchmark 测试redis性能 入门介绍 传统关系数据库ACID A(原子性)C(一致性)I(独立性)D(持久性) kv键值数据库redis,memcache,tair,BerkeleyDB:分布式内存数据库缓存 文档数据库MongoDB,CouchDB:分布式文件存储数据库 列存储数据库Hbase,Cassandra:分布式文件系统 图关系数据库Neo4J,InfoGrid:存放一些关系图,而不是图形,比如社交网络,广告推荐系统 NoSQL分布式数据库中CAP原理 C(强一致性)A(可用性)P(分区容错性),只能3选2。 Redis是单进程处理客户端的请求,对读写等事件的响应是通过对epoll函数的包装来做到的,Redis的实际处理速读完全依靠主进程的执行效率,分布式内存数据库。 默认16个数据库 Redis索引都是从0开始 select 切换数据库 Dbsize 查看当前数据库的key的数量 keys * 查看当前数据库所有key keys k? 查看跟k有关的所有key Flushdb 清空当前库 Flushall 通杀全部库 Redis五大数据类型 1.String(字符串),是二进制安全,redis的string可以包含任何数据,一个redis中字符串value对多可以是512M。 2.Hash(哈希,类似java里的map),是一个string类型的field和value的映射表,hash特别适合用于存储对象。 3.List(列表),它的底层实际是个链表,可以添加一个元素到列表的头部或尾部。 4.Set(集合),是String类型的无序集合,无重复,它是通过HashTable实现的。 5.Zset(有序集合),每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。 1.key(键) exists key 查看是否有当前keymove 剪切 如:move k3 2 expire key 为key设置过期时间 ttl key 查看声明周期 -1(表示永不过期) -2(表示已过期) type key查看key是什么类型 del key删除key 2.String(字符串) append k1 12345 为key追加字符 incr key 单步/单数递增 (一定是数字再能进行加减) decr key单数递减 incrby key 3 多步递增 decrby key 3 多不递减 getrange k1 0 3 后面的异常 setrange k1 0 xxx 修改前三个为xxx setnx 如果加入的内容存在,则不加入,相反不存在,则加入,set不会判断会直接覆盖,setnx则判断。 mset 新增多个key mget 查询多个key 3.list(列表) lpush lpush list01 1 2 3 左边加入 rpush rpush list02 1 2 3 右边加入 lrange 查看list集合 如:lrange list01 0 -1 lpop list01 删左边第一个 rpop list01 删右边第一个 lindex list01 1 查看索引 llen list01 查看列表里元素数量 lrem list01 2 3 意思删除2个3 ltrim list01 0 4 截取索引0-4,再加进去 rpoplpush list01 list02 意思将list01里最后一个,加入list02第一个 lset list01 1 x 将list01里下标1的替换为x linsert list01 before x java 将java新增到x前面 linsert list02 after x oracle 将oracle新增到x后面 Reids里如果值移除,对应的键也就消失了 4.set(集合) sadd set01 1 1 2 2 3 3 添加集合 smembers key 查看集合 sismember set01 1 查看集合里有没有对应值 1有 0无 scard set01 获取集合里元素个数 srem set01 3 根据value删除集合中元素 srandmember key 随机出几个数 spop key 随机出栈 smove set01 set02 3 意思将set01里的值3,移到set02 数学集合类:差集sdiff set01 set02,交集sinter set01 set02,并集sunion set01 set02, 5.Hash(哈希):kv模式不变,但V是一个键值对 hset user id 11 写入单个键值 hget user id 查看单个 hmset role id 1 name w5 get 19 写入多个键值 hmget role id name get 查看多个 hgetall role 查看多个 hdel role get 删除指定的V hien user 查看集合数量 hexists user id 判断集合里id有没有 <1>有 <0>没有 hkeys user 查看所有K hvals user 查看多有V hincrby user age 2 在原有值上递增2 hincrbyfloat user age 2.5 在原有值上递增2.5,可以是小数 hsetnx 6.Zset(有序集合): 在set基础上,加一个score值。 之前set是k1 v1 v2 v3 现在Zset是 k1 score1 v1 score2 v2 score3 v3 zadd zset01 60 v1 70 v2 80 v3 90 v4 创建zset01 zrange zset01 0 -1 查看所有 zrangebyscore zset01 60 (90 查看60-90之间分数 zrem zset01 删除score下对于的value值。 zcard zset01 统计数量 zcount zset01 60 70 统计score-score之间的数量 zrank zset 01 v1 根据value值获得下标位置 zscore zset 01 v1根据value值获得分数 zrevrank zset01 v2 根据value值逆向获得下标位置 zrevrange zset01 0 -1 逆向查看所有 zrenrangebyscore zset01 90 60 逆向查看90-60之间分数 解析配置文件redis.conf Units单位 INCLUDES包含 GENGRAL通用 daemonize yes 默认no改为yes tcp-backlog 511 是一个连接队列,backlog队列总和=未完成三次握手+已完成三次握手,在高并发环境下你需要一个高backlog值来避免满客户段连接问题 timeout 0 0代表会话一直连着 tcp-keepalive 300 如果为0,则不会进行keepalive检测,建议设置成60 loglevel notice 一共四个日志级别,默认notice级别 logfile "" 日志名字 SNAPSHOTTING快照rdb REPLICATION复制 SECURITY安全 127.0.0.1:6379> config get dir 访问redis.conf配置文件 config get requirepass 查看是否有密码 config set requirepass "123456" 设置密码 auth 123456 登录 syslog-enabled no 是否把日志输出到syslog中 syslog-ident redis 指定syslog里的日志标志 syslog-facility local0指定syslog设备,值可以是user或local0-local7 LIMITS限制 lru算法:最近最少使用, maxclients 默认连接数 maxmemory maxmemory-policy noeviction 缓存清楚策论,默认缓存永不过期 volatile-lru: 使用LRU算法移除key,只对设置了过期时间的键 allkeys-lru: 使用LRU算法移除key volatlie-random:在过期集合中移除随机的key,只对设置了过期时间的键 allkeys-random:移除随机的key volatlie-ttl: 移除那些TTL值最小的key,那些最近要过期的key noeviction: 不进行移除,针对写操作,只返回错误信息 maxmemory-samples 5 APPEND ONLY MODE追加aof Redis的持久化 rdb(Redis DataBase) 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时将快照文件直接读到内存里。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 rdb的缺点是最后一次持久化后的数据可能丢失 Fork:复制一个与当前进程一样的进程,新进程的所有数据都和原进程一直,但是是一个全新的进程,并作为原进程的子进程。 rdb保存的是dump.rdb文件注:16库文件都在里面测试过 配置位置:快照里有设置2分钟保存一次rdb, 诉求两分钟以内要求你的key改动过大于等于10次以上,形成dump.rdb备份文件,然后故意搞破坏,恢复 关闭服务->rm -f dump.rdb先删除->在启动服务赶紧添加数据->设置是启动服务后2分钟会出现dump.rdb备份文件 先备份cp dump.rdb dump_dball.rdb->flushall-如何恢复呢?->cp dump_dball.rdb dump.rdb 再复制回来。 save秒钟写操作次数:1分钟内改了1万次 或5分钟内改了10次 或15分钟内改了1次 save 自己写入rdb Stop-writes-on-bgsave-error 如果后台出错了前台停止写 rdbcompression 可以设置是否进行压缩存储 rdbchecksum 在存储快照后,还可以让redis使用CRC84算法进行数据效验,但这样会增加10%性能消耗,如果希望提升性能可以关闭 dbfilename SNAPSHOTTING快照里默认只认识dump.rdb,也可以自己改认识dump.rdb dir 获得目录 redis备份最好是两台机器 如何触发RDB快照 默认配置可以,手动save可以,拷贝,bgsave:后台异步进行快照操作,Flushdb:可以但没有意义 如何恢复 优势 适合大规模的数据恢复,对数据完整性和一致性要求不高 劣势 在一定时间内做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改 fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑 如何停止 动态所有停止rdb,保存规则的方法:redis-cli config set save "" 小总结 rdb是一个非常紧凑的文件,与AOF相比恢复的数据时rdb会更快一些, 内存中的数据对象 <-rdbLoad rdbSave->磁盘中的rdb文件 aof(Append Only File) 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录) 只需追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据, 换言之,redis启动的话就根据日志文件的内容将写指令从前到后执行一次完成数据的回复工作。 Aof保存的是appendonly.aof文件 配置位置 APPEND ONLY MODE追加里将no改为yes->删除所有rdb文件->开启服务set数据会出现appendonly.aof,关闭服务会出现 dump.rdb->再删除rdb文件->通过appendonly.aof文件恢复->vi appendonly.aof进入删除Flushdb ->这时就恢复了->搞破坏vi appendonly.aof随便打先字母,这时服务就无法启动了,且rdb和aof可以同时存在-> 修复aof文件注rdb文件也可修复,redis-check-aof --fix appendonly.aof-> Appendfsync:Always:同步持久化,每次数据变更记录到硬盘,性能差数据完整性好。 Everysec:出厂默认推荐,异步操作,每秒记录,如果一秒Down机,有数据丢失 No-appendfsync-on-rewrite:重写时是否可以运用Appendfsync,默认no即可,保证数据安全性 Auto-aof-rewrite-min-size:设置重写的基准值 Auto-aof-rewrite-percentage:设置重写的基准值 Aof启动/修复/恢复 Rewrite 是什么:aof采用文件追加方式,文件会越来越大为避免出现此情况,新增了重写机制 当aof文件的大小超过所设定的值时,Redis就会启动aof文件的内容压缩 只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof 你还没有重要到要让我动用情商的地步,因为没有实力的愤怒毫无意义 重写原理:aof文件持续增长而过大时,会fork出一条新进程来将文件重写,量变引起质变 触发机制:Redis会记录上次重写时的aof大小,默认配置是当aof文件大小是上次rewrite后大小的一倍且文件大于64M时修改,3G起步 优势 每秒同步 Appendfsync Always 每修改同步 Appendfsync everysec 不同步 Appendfsync no 劣势 相同数据集而言aof文件远大于rdb文件,恢复速度慢于rdb aof运行效率要慢于rdb,每秒同步策略效果较好,不同步效率和rdb相同 小总结 客户端(命令)->服务端(启动)->aof文件(加载) rdb能够在指定的时间间隔对你的数据进行快照存储, aof记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据, aof命令以redis协议追加保存每次写的操作到文件末尾, redis还能对aof文件进行后台重写,使得aof文件体积不至于过大, 只做缓存:如果你只希望你的数据在服务器上运行的时候存在,你也可以不适应任何持久化方式, 同时开启两种持久化方式:rdb的数据不实时,rdb更适合用于备份数据库,aof在不断变化不好备份 性能建议:建议只在Slave上持久化rdb文件,而只要15分钟备份一次就够了,只保留save 900 1这条规则 aof好处是在最恶劣的情况下也只会丢失不超过2秒的数据 Redis的事务 是什么:可以一次执行多个命令,本质是一组命令的集合, 一个事物中所有命令都会序列化,按顺序地串行化执行执行而不会被其他命令插入,不许加塞 能干嘛:一个队列中,一次性,顺序性,排他性的执行一系列命令 怎么玩:事务常用命令:discard取消事务, exec执行需所有事务, multi标记一个事物块的开始, watch key[key...]监视一个或多个key,如果在事务执行之前这个(或这些)key被其他命令改动过事务打断 unwatch取消watch命令对所有key的监视, 正常执行, multi->set k1 v1->exec 放弃事务, multi->set k2 v2->discard 全体连坐, multi->set k1 v1 sett k2 v2 set k3 v3->exec 要么全成功,要么全失败 冤头债主, multi->incr k1 incr k1 set k2 2 get k3 对的放行,错的挂掉,Redis对事务部分支持 watch监控 悲观锁 每次去拿数据的时候都认为别人会修改,所以每次拿数据的时候都上锁,适用于备份 乐观锁 每次去拿数据的时候都认为别人不会修改,所以不上锁,但是在更新的时候判断在此期间有没有人更新数据 提交版本必须大于记录当前版本才能执行更新,适用于多读的应用类型,这样可以提高吞吐量 CAS set balance 100 get dabt 0 watch balance multi decrby balance 20 减 incrby dabt 20 加 watch balance->set balance 500->unwatch->watch balance->multi->set balance 80->set dabt 20->exec 一旦执行了exec之前加的监控锁都会被取消掉 总结 watch指令,类似乐观锁,事务提交时如果key的值已被别的客户端改变,整个事务列队不会被执行 3阶段:开启,入队,执行 3特性:单独隔离操作,不保证原子性 Redis的发布订阅:企业一般不会有Redis的发布订阅 是什么:进程间的一种消息通信模式,发送者(pub)发送信息,订阅者(sub)接受信息 命令: psubscribe, 订阅多个,通配符*如psubscribe CCTV*,publish CCTV1 zhongyang1 pubsub, publish, 发布信息如publish c1 hellword, punsubscribe, subscribe, 订阅信息如subscribe c1 c2 c3 unsubscrib 案例: Redis的复制 是什么: 也就是我们所说的主从复制,主机数据更新后根据配置和策略 自动同步到备机的master/slaver机制,master以写为主,slaver以读为主 能干嘛: 读写分离 容灾恢复 怎么玩: 配从库不配主库 从库配置:slaveof主库IP主库端口,每次与master断开后,都需要重新连接,除非你配置进redis.conf 修改配置文件细节操作: 拷贝多个redis.conf文件 开启daemonize yes pid文件名字 指定端口 log文件名字 Dump.rdb名字 粘贴三个redis6379/80/81.conf->修改文集详情如上-> 三个分别进入bin目录下启动各自redis6379/80/81.conf服务->bin目录下会出现日志文件->ps -ef|grep redis查看是否正常启动->info replication显示三者都是平等关系master-> 配置主从,6379终点set k1 v1,6380和6381 slaveof 127.0.0.1 6379 就OK了-> 当主机挂掉了,从机依原地待命->当从机挂掉,master断开后,都需要重新连接除非你配置进redis.conf 常用三招: 一主二仆,Init,info replication查看主从关系 一个Master两个Slave 日志查看 主从问题演示 薪火相传, 6379<--6380 slaveof 127.0.0.1 6379<--6381 slaveof 127.0.0.1 6380,中间的6380依旧是从机 反客为主 当主机挂了->从机选出新主机 slaveof on one ->设置从机跟随新主机slaveof 127.0.0.1 6380 复制原理 slave启动成功连接到master后会发送一个sync命令 全量复制和增量复制 但是只要是重新连接master,一次完全同步全量复制将被自动执行 哨兵模式 sentinel反客为主的自动版能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库 调整结构:6379带着80,81 在myredis下新建sentinel.conf->vi sentinel.conf指定监控主库sentinel monitor host6379 127.0.0.1 6379 1 ->cd ./bin redis-sentinel /myredis/sentinel.conf-> 复制的缺点 复制延迟 Redis的Java客户端Jedis 准备jar包:jedis.jar commons-pool2-2.2.jar 测试链接: Jedis jedis = new Jedis("192.168.15.20",6379); System.out.println(jedis.ping()); Jedis主从复制:Jedis jedis_M = new Jedis("192.168.15.20",6379); Jedis jedis_S = new Jedis("192.168.15.20",6380); jedis_S.slaveof("192.168.15.20",6379); jedis_M.set("k2","v2"); String result = jedis_S.get("k2"); System.out.println(result); Jedis_JedisPool: 当力有六中写法,懒汉,恶汉,恶汉线程安全 public class JedisPoolUtil{ private static volatile JedisPool jedisPool = null; private JedisPoolUtil(){} public static JedisPool getJedisPoolInstance(){ if(null == jedisPool){ synchronized(JedisPoolUtil.class){//同步块锁定一个对象 if(null == jedisPool){ JedisPoolConfig poolConfig = new JedisPoolCfong();//连接池的配置 poolConfig.setMaxActive(1000);//控制一个pool可分配多少个jedis实例 poolConfig.setMaxIdle(32); //控制一个pool最多有多少个jedis空闲 poolConfig.setMaxWait(100*1000);//最大等待时间 poolConfig.setTestOnBorrow(true);//检查连接是否可用 jedisPool = new JedisPool(jedisPool,"192.168.15.20",6379); } } } return jedisPool } public static void release(JedisPool jedisPool,Jedis jedis){//关闭连接池里的实例 if(null != jedis{ jedisPool.returnResourceObject(jedis); } } } Redis的集群 Lua脚本语言 Redis和Lua集合 Redis整合spring Redis集群实现Tomcat集群的Session共享
安装解压文件make下查看是否安装gcc编译工具修改redis下redis.conf文件 GENERAL daemonize no改为yes在cd /usr/local/redis目录下 ps -ef|grep redis 查看服务是否启动进入usr/local/bin下启动服务:redis-server /redis/redis.confredis-cli -p 6379ping 说明启动成功shutdown 关闭服务进入usr/local/bin下:redis-benchmark 测试redis性能
入门介绍传统关系数据库ACID A(原子性)C(一致性)I(独立性)D(持久性)kv键值数据库redis,memcache,tair,BerkeleyDB:分布式内存数据库缓存文档数据库MongoDB,CouchDB:分布式文件存储数据库列存储数据库Hbase,Cassandra:分布式文件系统图关系数据库Neo4J,InfoGrid:存放一些关系图,而不是图形,比如社交网络,广告推荐系统NoSQL分布式数据库中CAP原理 C(强一致性)A(可用性)P(分区容错性),只能3选2。Redis是单进程处理客户端的请求,对读写等事件的响应是通过对epoll函数的包装来做到的,Redis的实际处理速读完全依靠主进程的执行效率,分布式内存数据库。默认16个数据库Redis索引都是从0开始select 切换数据库Dbsize 查看当前数据库的key的数量keys * 查看当前数据库所有keykeys k? 查看跟k有关的所有keyFlushdb 清空当前库Flushall 通杀全部库
Redis五大数据类型1.String(字符串),是二进制安全,redis的string可以包含任何数据,一个redis中字符串value对多可以是512M。2.Hash(哈希,类似java里的map),是一个string类型的field和value的映射表,hash特别适合用于存储对象。3.List(列表),它的底层实际是个链表,可以添加一个元素到列表的头部或尾部。4.Set(集合),是String类型的无序集合,无重复,它是通过HashTable实现的。5.Zset(有序集合),每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。
1.key(键)exists key 查看是否有当前keymove 剪切 如:move k3 2expire key 为key设置过期时间ttl key 查看声明周期 -1(表示永不过期) -2(表示已过期)type key查看key是什么类型del key删除key
2.String(字符串)append k1 12345 为key追加字符incr key 单步/单数递增 (一定是数字再能进行加减)decr key单数递减incrby key 3 多步递增decrby key 3 多不递减getrange k1 0 3 后面的异常setrange k1 0 xxx 修改前三个为xxxsetnx 如果加入的内容存在,则不加入,相反不存在,则加入,set不会判断会直接覆盖,setnx则判断。mset 新增多个key mget 查询多个key
3.list(列表)lpush lpush list01 1 2 3 左边加入rpush rpush list02 1 2 3 右边加入lrange 查看list集合 如:lrange list01 0 -1lpop list01 删左边第一个rpop list01 删右边第一个lindex list01 1 查看索引llen list01 查看列表里元素数量lrem list01 2 3 意思删除2个3ltrim list01 0 4 截取索引0-4,再加进去rpoplpush list01 list02 意思将list01里最后一个,加入list02第一个lset list01 1 x 将list01里下标1的替换为xlinsert list01 before x java 将java新增到x前面linsert list02 after x oracle 将oracle新增到x后面Reids里如果值移除,对应的键也就消失了
4.set(集合)sadd set01 1 1 2 2 3 3 添加集合smembers key 查看集合sismember set01 1 查看集合里有没有对应值 1有 0无scard set01 获取集合里元素个数srem set01 3 根据value删除集合中元素srandmember key 随机出几个数spop key 随机出栈smove set01 set02 3 意思将set01里的值3,移到set02数学集合类:差集sdiff set01 set02,交集sinter set01 set02,并集sunion set01 set02,
5.Hash(哈希):kv模式不变,但V是一个键值对hset user id 11 写入单个键值hget user id查看单个hmset role id 1 name w5 get 19 写入多个键值hmget role id name get 查看多个hgetall role 查看多个hdel role get删除指定的Vhien user查看集合数量hexists user id判断集合里id有没有 <1>有 <0>没有hkeys user查看所有Khvals user查看多有Vhincrbyuser age 2 在原有值上递增2hincrbyfloat user age 2.5 在原有值上递增2.5,可以是小数hsetnx
6.Zset(有序集合):在set基础上,加一个score值。之前set是k1 v1 v2 v3现在Zset是 k1 score1 v1 score2 v2 score3 v3zadd zset01 60 v1 70 v2 80 v3 90 v4 创建zset01zrange zset01 0 -1 查看所有zrangebyscore zset01 60 (90 查看60-90之间分数zrem zset01 删除score下对于的value值。zcard zset01 统计数量zcount zset01 60 70 统计score-score之间的数量zrank zset 01 v1 根据value值获得下标位置zscore zset 01 v1根据value值获得分数zrevrank zset01 v2 根据value值逆向获得下标位置zrevrange zset01 0 -1 逆向查看所有zrenrangebyscore zset01 90 60 逆向查看90-60之间分数
解析配置文件redis.confUnits单位INCLUDES包含GENGRAL通用 daemonize yes 默认no改为yes tcp-backlog 511 是一个连接队列,backlog队列总和=未完成三次握手+已完成三次握手,在高并发环境下你需要一个高backlog值来避免满客户段连接问题 timeout 0 0代表会话一直连着 tcp-keepalive 300 如果为0,则不会进行keepalive检测,建议设置成60 loglevel notice 一共四个日志级别,默认notice级别 logfile "" 日志名字SNAPSHOTTING快照rdbREPLICATION复制SECURITY安全 127.0.0.1:6379> config get dir 访问redis.conf配置文件 config get requirepass 查看是否有密码 config set requirepass "123456" 设置密码 auth 123456 登录 syslog-enabled no 是否把日志输出到syslog中 syslog-ident redis 指定syslog里的日志标志 syslog-facility local0指定syslog设备,值可以是user或local0-local7LIMITS限制 lru算法:最近最少使用, maxclients 默认连接数 maxmemory maxmemory-policy noeviction 缓存清楚策论,默认缓存永不过期 volatile-lru:使用LRU算法移除key,只对设置了过期时间的键 allkeys-lru:使用LRU算法移除key volatlie-random:在过期集合中移除随机的key,只对设置了过期时间的键 allkeys-random:移除随机的key volatlie-ttl:移除那些TTL值最小的key,那些最近要过期的key noeviction:不进行移除,针对写操作,只返回错误信息 maxmemory-samples 5 APPEND ONLY MODE追加aof
Redis的持久化 rdb(Redis DataBase) 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时将快照文件直接读到内存里。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 rdb的缺点是最后一次持久化后的数据可能丢失 Fork:复制一个与当前进程一样的进程,新进程的所有数据都和原进程一直,但是是一个全新的进程,并作为原进程的子进程。 rdb保存的是dump.rdb文件注:16库文件都在里面测试过 配置位置:快照里有设置2分钟保存一次rdb, 诉求两分钟以内要求你的key改动过大于等于10次以上,形成dump.rdb备份文件,然后故意搞破坏,恢复 关闭服务->rm -f dump.rdb先删除->在启动服务赶紧添加数据->设置是启动服务后2分钟会出现dump.rdb备份文件 先备份cp dump.rdb dump_dball.rdb->flushall-如何恢复呢?->cp dump_dball.rdb dump.rdb 再复制回来。 save秒钟写操作次数:1分钟内改了1万次 或5分钟内改了10次 或15分钟内改了1次 save 自己写入rdb Stop-writes-on-bgsave-error 如果后台出错了前台停止写 rdbcompression 可以设置是否进行压缩存储 rdbchecksum 在存储快照后,还可以让redis使用CRC84算法进行数据效验,但这样会增加10%性能消耗,如果希望提升性能可以关闭 dbfilename SNAPSHOTTING快照里默认只认识dump.rdb,也可以自己改认识dump.rdb dir 获得目录 redis备份最好是两台机器 如何触发RDB快照 默认配置可以,手动save可以,拷贝,bgsave:后台异步进行快照操作,Flushdb:可以但没有意义 如何恢复 优势适合大规模的数据恢复,对数据完整性和一致性要求不高 劣势在一定时间内做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑 如何停止动态所有停止rdb,保存规则的方法:redis-cli config set save "" 小总结rdb是一个非常紧凑的文件,与AOF相比恢复的数据时rdb会更快一些,内存中的数据对象<-rdbLoadrdbSave->磁盘中的rdb文件
aof(Append Only File) 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录) 只需追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据, 换言之,redis启动的话就根据日志文件的内容将写指令从前到后执行一次完成数据的回复工作。 Aof保存的是appendonly.aof文件 配置位置 APPEND ONLY MODE追加里将no改为yes->删除所有rdb文件->开启服务set数据会出现appendonly.aof,关闭服务会出现 dump.rdb->再删除rdb文件->通过appendonly.aof文件恢复->vi appendonly.aof进入删除Flushdb ->这时就恢复了->搞破坏vi appendonly.aof随便打先字母,这时服务就无法启动了,且rdb和aof可以同时存在-> 修复aof文件注rdb文件也可修复,redis-check-aof --fix appendonly.aof-> Appendfsync:Always:同步持久化,每次数据变更记录到硬盘,性能差数据完整性好。 Everysec:出厂默认推荐,异步操作,每秒记录,如果一秒Down机,有数据丢失 No-appendfsync-on-rewrite:重写时是否可以运用Appendfsync,默认no即可,保证数据安全性 Auto-aof-rewrite-min-size:设置重写的基准值 Auto-aof-rewrite-percentage:设置重写的基准值 Aof启动/修复/恢复 Rewrite 是什么:aof采用文件追加方式,文件会越来越大为避免出现此情况,新增了重写机制 当aof文件的大小超过所设定的值时,Redis就会启动aof文件的内容压缩 只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof 你还没有重要到要让我动用情商的地步,因为没有实力的愤怒毫无意义 重写原理:aof文件持续增长而过大时,会fork出一条新进程来将文件重写,量变引起质变 触发机制:Redis会记录上次重写时的aof大小,默认配置是当aof文件大小是上次rewrite后大小的一倍且文件大于64M时修改,3G起步 优势 每秒同步 Appendfsync Always 每修改同步 Appendfsync everysec 不同步 Appendfsync no 劣势 相同数据集而言aof文件远大于rdb文件,恢复速度慢于rdb aof运行效率要慢于rdb,每秒同步策略效果较好,不同步效率和rdb相同 小总结 客户端(命令)->服务端(启动)->aof文件(加载) rdb能够在指定的时间间隔对你的数据进行快照存储, aof记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据, aof命令以redis协议追加保存每次写的操作到文件末尾, redis还能对aof文件进行后台重写,使得aof文件体积不至于过大, 只做缓存:如果你只希望你的数据在服务器上运行的时候存在,你也可以不适应任何持久化方式, 同时开启两种持久化方式:rdb的数据不实时,rdb更适合用于备份数据库,aof在不断变化不好备份 性能建议:建议只在Slave上持久化rdb文件,而只要15分钟备份一次就够了,只保留save 900 1这条规则 aof好处是在最恶劣的情况下也只会丢失不超过2秒的数据
Redis的事务 是什么:可以一次执行多个命令,本质是一组命令的集合, 一个事物中所有命令都会序列化,按顺序地串行化执行执行而不会被其他命令插入,不许加塞 能干嘛:一个队列中,一次性,顺序性,排他性的执行一系列命令 怎么玩:事务常用命令:discard取消事务, exec执行需所有事务, multi标记一个事物块的开始, watch key[key...]监视一个或多个key,如果在事务执行之前这个(或这些)key被其他命令改动过事务打断 unwatch取消watch命令对所有key的监视, 正常执行,multi->set k1 v1->exec 放弃事务,multi->set k2 v2->discard 全体连坐,multi->set k1 v1 sett k2 v2 set k3 v3->exec 要么全成功,要么全失败 冤头债主,multi->incr k1 incr k1 set k2 2 get k3 对的放行,错的挂掉,Redis对事务部分支持 watch监控 悲观锁 每次去拿数据的时候都认为别人会修改,所以每次拿数据的时候都上锁,适用于备份乐观锁 每次去拿数据的时候都认为别人不会修改,所以不上锁,但是在更新的时候判断在此期间有没有人更新数据 提交版本必须大于记录当前版本才能执行更新,适用于多读的应用类型,这样可以提高吞吐量 CAS set balance 100 get dabt 0 watch balance multi decrby balance 20 减 incrby dabt 20 加 watch balance->set balance 500->unwatch->watch balance->multi->set balance 80->set dabt 20->exec 一旦执行了exec之前加的监控锁都会被取消掉 总结 watch指令,类似乐观锁,事务提交时如果key的值已被别的客户端改变,整个事务列队不会被执行 3阶段:开启,入队,执行 3特性:单独隔离操作,不保证原子性
Redis的发布订阅:企业一般不会有Redis的发布订阅 是什么:进程间的一种消息通信模式,发送者(pub)发送信息,订阅者(sub)接受信息 命令:psubscribe,订阅多个,通配符*如psubscribe CCTV*,publish CCTV1 zhongyang1pubsub,publish,发布信息如publish c1 hellword,punsubscribe,subscribe,订阅信息如subscribe c1 c2 c3unsubscrib 案例:Redis的复制 是什么: 也就是我们所说的主从复制,主机数据更新后根据配置和策略 自动同步到备机的master/slaver机制,master以写为主,slaver以读为主 能干嘛: 读写分离 容灾恢复 怎么玩: 配从库不配主库 从库配置:slaveof主库IP主库端口,每次与master断开后,都需要重新连接,除非你配置进redis.conf 修改配置文件细节操作:拷贝多个redis.conf文件开启daemonize yespid文件名字指定端口log文件名字Dump.rdb名字 粘贴三个redis6379/80/81.conf->修改文集详情如上-> 三个分别进入bin目录下启动各自redis6379/80/81.conf服务->bin目录下会出现日志文件->ps -ef|grep redis查看是否正常启动->info replication显示三者都是平等关系master-> 配置主从,6379终点set k1 v1,6380和6381 slaveof 127.0.0.1 6379 就OK了-> 当主机挂掉了,从机依原地待命->当从机挂掉,master断开后,都需要重新连接除非你配置进redis.conf常用三招:一主二仆,Init,info replication查看主从关系 一个Master两个Slave 日志查看 主从问题演示薪火相传, 6379<--6380 slaveof 127.0.0.1 6379<--6381 slaveof 127.0.0.1 6380,中间的6380依旧是从机反客为主 当主机挂了->从机选出新主机 slaveof on one ->设置从机跟随新主机slaveof 127.0.0.1 6380 复制原理 slave启动成功连接到master后会发送一个sync命令全量复制和增量复制但是只要是重新连接master,一次完全同步全量复制将被自动执行 哨兵模式sentinel反客为主的自动版能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库调整结构:6379带着80,81 在myredis下新建sentinel.conf->vi sentinel.conf指定监控主库sentinel monitor host6379 127.0.0.1 6379 1->cd ./bin redis-sentinel /myredis/sentinel.conf-> 复制的缺点复制延迟
Redis的Java客户端Jedis准备jar包:jedis.jar commons-pool2-2.2.jar测试链接: Jedis jedis = new Jedis("192.168.15.20",6379); System.out.println(jedis.ping());
Jedis主从复制:Jedis jedis_M = new Jedis("192.168.15.20",6379); Jedis jedis_S = new Jedis("192.168.15.20",6380);jedis_S.slaveof("192.168.15.20",6379);
jedis_M.set("k2","v2");String result = jedis_S.get("k2");System.out.println(result);
Jedis_JedisPool: 当力有六中写法,懒汉,恶汉,恶汉线程安全public class JedisPoolUtil{private static volatile JedisPool jedisPool = null;private JedisPoolUtil(){}public static JedisPool getJedisPoolInstance(){if(null == jedisPool){ synchronized(JedisPoolUtil.class){//同步块锁定一个对象 if(null == jedisPool){ JedisPoolConfig poolConfig = new JedisPoolCfong();//连接池的配置 poolConfig.setMaxActive(1000);//控制一个pool可分配多少个jedis实例 poolConfig.setMaxIdle(32); //控制一个pool最多有多少个jedis空闲 poolConfig.setMaxWait(100*1000);//最大等待时间 poolConfig.setTestOnBorrow(true);//检查连接是否可用
jedisPool = new JedisPool(jedisPool,"192.168.15.20",6379); } }}return jedisPool}public static void release(JedisPool jedisPool,Jedis jedis){//关闭连接池里的实例if(null != jedis{ jedisPool.returnResourceObject(jedis);}}}
Redis的集群
Lua脚本语言
Redis和Lua集合
Redis整合spring
Redis集群实现Tomcat集群的Session共享