zoukankan      html  css  js  c++  java
  • AOF和数据类型02

    redis 使用场景

    1.缓存(redis数据存储在内存)
    2.会话保持(生命周期TTL)
    3.消息队列(list类型)
    4.计数器(string类型)
    5.QQ,微信共同好友(集合)
    6.排行榜(有序集合)
    7.存储(hash类型)
    

    持久化

    将内存中的数据写入磁盘
    

    1.持久化模式

    1.RDB模式,支持高并发,save
    2.AOF模式,数据一致性,
    

    2.RDB模式

    可以在指定的时间间隔内生成数据集的'时间点快照'
    

    1)RDB模式工作方式

    a06cx1.md.jpg

    1.默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。
    你'可以设置'让Redis在N秒内至少有M次数据集改动时保存数据集,
    或者你也可以手动调用SAVE或者BGSAVE命令。
    save	:内存中的数据写入磁盘中的时候(dump.rdb),'不支持'数据的写入
    bgsave	:内存中的数据写入磁盘中的时候,'支持'数据的写入
    
    2.在上文中我们已经在配置文件中做过对应的配置:
    例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:
    save 60 1000
    
    3.当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:(# save原理)
    Redis 调用 fork() ,同时拥有父进程和子进程。
    子进程将数据集写入到一个临时的 RDB 文件中。当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
    
    #Redis关闭的时候自动生成dump.rdb文件(自动save)
    

    2)配置rdb持久化

    #编辑配置文件
    [root@db01 redis]# vim /service/redis/6379/redis.conf
    #监听地址
    bind 172.16.1.52 127.0.0.1
    #端口
    port 6379
    #后台启动
    daemonize yes
    #pid文件位置
    pidfile /service/redis/6379/redis_6379.pid
    #日志级别
    loglevel notice
    #指定日志文件
    logfile "/service/redis/6379/redis_6379.log"
    #设置redis密码
    requirepass 123
    
    #持久化数据文件存储位置
    dir /etc/redis/6379
    #rdb持久化数据文件名
    dbfilename dump.rdb
    #900秒(15分钟)内有1个更改
    save 900 1
    #300秒(5分钟)内有10个更改
    save 300 10
    #60秒(1分钟)内有10000个更改
    save 60 10000
    
    #后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致
    stop-writes-on-bgsave-error yes
    #导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做
    rdbcompression yes
    #导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致
    rdbchecksum yes
    
    #持久化默认是rdb模式
    

    3)RDB持久化优点

    1.RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件'适合用于备份'。
    例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
    2.RDB非常适合于'灾难恢复',作为一个紧凑的单一文件,可以被传输到远程的数据中心。(Redis不同实例的rdp文件是'通用'的)
    3.RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是'启动(fork)一个子进程',
    由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。所以Redis服务端不会'阻止数据的写入'
    4.RDB在'重启' 保存了大数据集的实例时比AOF要快。(rdb文件是二进制文件)
    
    #dump.rdb文件记录的是Redis数据库的'结果',appendonly.aof文件记录的是Redis语句的'过程'
    #rdb模式和AOF模式一样,都是调用Fock子进程来写入磁盘,所以不会阻止客户端数据的写入
    

    4)RDB持久化缺点

    1.当你需要在Redis停止工作(例如'停电')时最小化数据丢失,RDB可能不太好。
    你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。
    然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。
    2.RDB需要经常调用fork()子进程来持久化到磁盘。
    如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。
    AOF也需要fork(),但是你可以'调整多久频率重写'日志而不会有损(trade-off)持久性(durability)。
    

    5)RDB模式优缺点总结

    1.优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的。
    2.缺点:会有数据丢失、Fock进程调用频繁导致服务停止几秒
    

    3.AOF持久化

    AOF(append only file)只追加文件,
    记录服务器执行的'所有写操作命令'(类似于mysql的binlog),并在服务器启动时,通过重新执行这些命令来还原数据集(指定目录执行appendonly.aof)。 
    AOF 文件中的命令全部以 Redis 协议的格式来保存(*之间的那一段是一条命令),新命令会被追加到文件的末尾。
    

    1)配置AOF持久化

    #修改配置文件
    [root@db01 redis]# vim /service/redis/6379/redis.conf
    #监听地址
    bind 172.16.1.52 127.0.0.1
    #端口
    port 6379
    #后台启动
    daemonize yes
    #pid文件位置
    pidfile /service/redis/6379/redis_6379.pid
    #日志级别
    loglevel notice
    #指定日志文件
    logfile "/service/redis/6379/redis_6379.log"
    #设置redis密码
    requirepass 123
    
    #持久化数据文件存储位置
    dir /etc/redis/6379
    #rdb持久化数据文件名
    #dbfilename dump.rdb
    #900秒(15分钟)内有1个更改
    #save 900 1
    #300秒(5分钟)内有10个更改
    #save 300 10
    #60秒(1分钟)内有10000个更改
    #save 60 10000
    
    #是否打开AOF日志功能
    appendonly yes
    #每一条命令都立即同步到AOF
    appendfsync always
    #每秒写一次
    #appendfsync everysec
    #写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到AOF
    #appendfsync no
    
    #正在导出rdb快照的过程中,要不要停止同步aof
    no-appendfsync-on-rewrite yes
    #aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次
    auto-aof-rewrite-percentage 100
    #aof文件,至少超过64M时,重写
    #auto-aof-rewrite-min-size 64mb
    

    2)AOF模式的优点

    1.使用AOF Redis会更具有'可持久性'(durable):
    你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。
    使用'默认的每秒'fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便损失也就仅仅只损失一秒钟的写数据。或几次数据的写入
    2.AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),'redis-check-aof工具'也可以很轻易的修复(删除坏掉的)。
    3.当AOF文件变得很大时,Redis会'自动在后台进行重写'(bgrewriteaof)。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。
    4.AOF文件里面包含'一个接一个的操'作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,'如果此时并没有执行重写,你仍然可以保存你的数据集',你只要停止服务器,删除最后一条命令,然后重启Redis就可以。
    
    redis-check-aof
    

    3)AOF重写功能(bgrewriteaof)

    1.因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。
    
    2.为了处理这种情况, Redis 支持一种有趣的特性:可以在不断服务客户端的情况下,对 AOF 文件进行重建。执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件'包含重建当前数据集所需的最少命令'。使RedisAOF的启动速度趋近于rdb模式
    
    BGREWRITEAOF
    

    4)AOF持久化缺点

    1.对同样的数据集,AOF文件通常要'大于'等价的RDB文件。
    2.AOF可能比RDB'慢',这取决于准确的fsync策略。通常fsync设置为每秒一次的话,性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。
    

    5)AOF持久化优缺点总结

    优点:可以最大程度保证数据不丢失
    缺点:日志记录量级比较大
    

    4.RDB与AOF

    1)应该应用哪一个

    1.一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性,你应该'同时使用两种持久化功能。',默认优先读取AOF,再读取rdb文件
    2.
    
    
    

    2)RDB与AOF相互作用

    1.在'版本号大于等于2.4的Redis中',
    BGSAVE 执行的过程中,不可以执行 BGRWRITEAOF,
    反过来说,在 BGRWRITEAOF 执行的过程中,也不可以执行 BGSAVE 。
    
    2.这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。
    如果 BGSAVE 正在执行,并且用户调用 BGRWRITEAOF 命令,
    那么服务器将向用户回复一个 OK 状态,并告知用户,BGRWRITEAOF 已经被预定执行;一旦 BGSAVE 执行完毕, BGRWRITEAOF 就会正式开始。
    
    3.当 Redis 启动时,如果 RDB 持久化和 AOF 持久化都被打开了,那么程序会'优先使用 AOF 文件来恢复数据集,因为 AOF 文件所保存的数据通常是最完整的。'
    

    3)备份Redis数据

    1.Redis 对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建,就不会进行任何修改。
    2.当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。(#Redis服务端不会阻止客户端数据的写入)
    3.这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。
    
    #以下是我们的建议:
    1.创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
    2.确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
    3.至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
    

    4)RDB持久化高级配置

    #编辑配置文件
    [root@db01 redis]# vim /etc/redis/6379/redis.conf
    #后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致
    stop-writes-on-bgsave-error yes
    #导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做
    rdbcompression yes
    #导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致
    rdbchecksum yes
    

    5)AOF持久化高级配置

    #编辑配置文件
    [root@db01 redis]# vim /etc/redis/6379/redis.conf
    #正在导出rdb快照的过程中,要不要停止同步aof
    no-appendfsync-on-rewrite yes
    #aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次
    auto-aof-rewrite-percentage 100
    #aof文件,至少超过64M时,重写
    #auto-aof-rewrite-min-size 64mb
    

    数据类型

    参考网站

    各个数据类型应用场景:

    类型 简介 特性 场景
    String(字符串) 二进制安全 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M 缓存,限流,计数器,分布式锁,分布式session
    Hash(字典) 键值对集合,即编程语言中的Map类型 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) 存储、读取用户信息、用户主页的访问量,组合查询
    List(列表) 链表(双向链表) 增删快,提供了操作某一段元素的API 1,最新消息排行等功能(比如朋友圈的个人动态时间线) 2,消息队列
    Set(集合) 哈希表实现,元素不重复 1、添加、删除,查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作 1、好友推荐时,根据tag求交集,大于某个阈值就可以推荐2、利用唯一性,统计访问网站的所有独立ip 3,赞 踩 标签
    Sorted Set(有序集合) 将Set中的元素增加一个权重参数score,元素按score有序排列 1.排行榜
    #Redis支持五种数据类型:
    	string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
    	
    key
        keys * 			获取所有的key
        select 0 		选择第一个库
        move key_name 1  将当前的数据库key移动到某个数据库,目标库有,则不能移动
        flushall     	清除所有库
        flushdb			清空当前库
        randomkey    	 随机获取所在库的key
        type key    	  key的类型
        
        set key1 value1 	 设置key
        get key1   			 获取key对应的value
        mset key1 value1 key2 value2 key3 value3
        mget key1 key2 key3
        del key1   			删除key
        exists key    		  判断是否存在key,返回 0 1
        expire key 10   	设置某个key 10秒过期自动删除
        pexpire key 1000 	用毫秒设置
        persist key     	删除过期时间
    
    
    #string类型,键值对
    string 是 redis 最基本的类型,可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
    string 可以包含任何数据。比如jpg图片或者序列化的对象。
    string 类型是 Redis 最基本的数据类型,一个string 类型的值最大能存储 512MB。
    
    string
        set name cxx
        	127.0.0.1:6379> set name 'syy is ku'
        	
        get name
        getrange name 0 -1        字符串分段
        	127.0.0.1:6379> getrange name 0 -1
        	
        getset name new_cxx       设置值,返回旧值
        	127.0.0.1:6379> getset name syy
    		127.0.0.1:6379> get name
    		
        mset key1 key2            批量设置
        mget key1 key2            批量获取
        setnx key value           不存在就插入(0没插入,1没插入)
        setex key time value      过期时间(expire)
        	127.0.0.1:6379> setex name 10 syy
        setrange key index value  从index开始替换value
        	127.0.0.1:6379> set name abcdefg
    		127.0.0.1:6379> setrange name 1 ha
    		127.0.0.1:6379> get name
        incr age        递增1
        incrby age 10   递增10
        decr age        递减1
        decrby age 10   递减10
        incrbyfloat     增减浮点数
        	127.0.0.1:6379> incrbyfloat num 0.1
        append          追加
        	127.0.0.1:6379> append num abc
        strlen          长度
        getbit/setbit/bitcount/bitop    位操作
    
    
    
    #hash类型,key 多个字段 多个值
    Redis hash 是一个键值(key=>value)对'哈希'。
    Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于'存储对象'。
    每个 hash 可以存储 2^32 -1 键值对(40多亿)
    
    hash
        hset myhash name cxx		设置单个键值对
        hget myhash name			获取单个键值对
        hmset myhash name cxx age 25 note "i am notes"
        hmget myhash name age note   
        hgetall myhash               获取所有的键值对
        hexists myhash name          是否存在
        hsetnx myhash score 100      设置不存在的
        hincrby myhash id 1          递增
        hdel myhash name             删除
        hkeys myhash                 只取key
        hvals myhash                 只取value
        hlen myhash                  长度
    
    #list列表,key 多个值 索引
    列表最多可存储 2^32 - 1 元素 (4294967295, 每个列表可存储40多亿)。
    列表内数据可以重复
    做消息队列
    
    list
        lpush mylist a b c  	左插入
        rpush mylist x y z  	右插入
        lrange mylist 0 -1  	查看列表内所有的数据
        lpop mylist  			左弹出元素
        rpop mylist  			右弹出元素
        llen mylist  			长度
        lrem mylist count value  删除列表内几个value
        lindex mylist 2          指定索引的值(索引取值)
        lset mylist 2 n          索引设值
        ltrim mylist 0 4         删除key(删除补集的元素)
        linsert mylist before a  插入
        linsert mylist after a   插入
        rpoplpush list list2     转移列表的数据(列表1的数据滚向列表2,排第一)
        	127.0.0.1:6379> rpoplpush mylist 0
    
    #set集合,无序集合,key 多个无序值
    Redis 的 Set 是 string 类型的无序集合,集合内元素具有'唯一性'
    集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
    集合中最大的成员数为 2^32 - 1(4294967295, 每个集合可存储40多亿个成员)。
    
    set
        sadd myset redis 		创建一个无序集合,添加数据Redis
        smembers myset       	查看集合
        srem myset redis         删除集合内数据
        sismember myset redis 	判断元素是否在集合中
        scard set_name       	集合内数据的个数
        sdiff | sinter | sunion  差集 | 交集 | 并集
        srandmember         	 随机获取集合中的元素
        spop                 	从集合中随机弹出一个元素
    
    
    #zset集合,有序集合,key 多个有序值(自动排序)
    Redis zset 和 set 一样也是string类型元素的集合
    不同的是每个元素都会'关联'一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
    zset的成员是唯一的,但分数(score)却'可以重复'。
    
    zset
        zadd zset 1 one
        zadd zset 2 two
        zadd zset 3 three
        zincrby zset 1 one              	增长分数(加减)
        zscore zset two                 	查看分数
        zrange zset 0 -1 withscores     	带依据查看排序(名值对)
        zrangebyscore zset 1 5 withscores   指定范围的值(名值对)
        zcount zset 1 5					  指定范围的数量
        zrangebyscore zset 10 25 withscores limit 1 2 分页(排名'头尾兼顾'+limit'顾头不顾腚')
        zcard zset  					元素数量
        Zcount zset  10 20				获得指定分数范围内的元素'个数'
        Zrem zset one two      			  删除一个或多个元素
        del zset						删除集合
        Zremrangebyrank zset 0 1 		 按照排名范围删除元素(头尾兼顾)
        Zremrangebyscore zset 0 1 		按照分数范围删除元素
        Zrevrange zset 0 -1    				   分数'最小'的元素排名为0
        Zrevrange zset 0 -1 withscores  		分数'最大'的元素排名为0
        
    127.0.0.1:6379> ZCOUNT linux9 50 100
    (integer) 4
    127.0.0.1:6379> ZRANGEBYSCORE linux9 50 100
    1) "jiwei"
    2) "shengwei"
    3) "banzhang"
    4) "xuewei"
    127.0.0.1:6379> ZRANGEBYSCORE linux9 50 100 WITHSCORES
    1) "jiwei"
    2) "50"
    3) "shengwei"
    4) "80"
    5) "banzhang"
    6) "90"
    7) "xuewei"
    8) "100"
    
    #服务器管理
        dump.rdb
        appendonly.aof
        //BgRewriteAof 异步执行一个aop(appendOnly file)文件重写
        会创建当前一个AOF文件体积的优化版本
        
        //BgSave 后台异步保存数据到磁盘,会在当前目录下创建文件dump.rdb
        //save同步保存数据到磁盘,'会阻塞主进程',别的客户端无法连接
        
        //client kill 关闭客户端连接
        //client list 列出所有的客户端
        
        //给客户端设置一个名称
          client setname myclient1
          client getname
          
         config get port	#不配置的走默认
         //configRewrite 对redis的配置文件进行改写
         
    rdb模式下,dump.rdb自动bgsave
    save 900 1
    save 300 10
    save 60 10000
    
    aof模式下,备份
    appendonly yes 开启持久化
    appendfsync everysec 每秒备份一次
    
    命令:
    bgsave异步保存数据到磁盘(快照保存)
    lastsave返回上次成功保存到磁盘的unix的时间戳
    shutdown'同步保存'到服务器并关闭redis服务器
    bgrewriteaof文件压缩处理(命令)
    
    
     #redis事务:
         隔离性,原子性, 
         步骤:  开始事务multi,队列命令,提交执行事务exec,取消事务discard(清空)
         		watch xx
                 multi  //开启事务
                 sadd myset a b c
                 sadd myset e f g
                 lpush mylist aa bb cc
                 lpush mylist dd ff gg    
                 exec
                 unwatch
    
    #订阅与发布:
        订阅频道:subscribe chat1				#持续监控
        发布消息:publish chat1 "hell0 ni hao"	#在某频道发布消息
        查看频道:pubsub channels				#查看所有频道
        查看某个频道的订阅者数量: pubsub numsub chat1
        退订指定频道: unsubscribe chat1   , punsubscribe
        订阅一组频道: psubscribe java.*
    
  • 相关阅读:
    Android研究之游戏开发处理按键的响应
    C语言指针的初始化和赋值
    Cloudera CDH 5集群搭建(yum 方式)
    未将对象引用设置到对象的实例--可能出现的问题总结
    内存泄漏以及常见的解决方法
    都能看懂的嵌入式linux/android alsa_aplay alsa_amixer命令行使用方法
    Life is hard!
    EasyUI基础入门之Resiable(可缩放)
    Android -- Looper.prepare()和Looper.loop() —深入版
    vi 命令 使用方法
  • 原文地址:https://www.cnblogs.com/syy1757528181/p/13462209.html
Copyright © 2011-2022 走看看