zoukankan      html  css  js  c++  java
  • redis分享

    Redis介绍

    ´Redis是一种基于键值对的NoSQL数据库。
    ´Redis基于内存来存放数据。
    ´速度快,官方给出读写性能可达到10万/秒(数据存内存,C语言实现,单线程架构)。
    ´丰富的数据结构:字符串、哈希、列表、集合、有序集合、位图、GEO等。
    ´丰富的功能:键过期,发布订阅,支持Lua脚本,事务,Pipeline。
    ´稳定的系统。
    ´客户端支持语言多。
    ´数据持久化,RDB、AOF。
    ´主从复制及分布式。
     
    Redis主要应用场景
    ´缓存,主要作用是优化数据访问速度,减轻后端数据源的压力。
    ´排行榜,TOP10,可利用Redis的列表或有序集合来实现。
    ´计数器,例如播放量、浏览数等计数。
    ´基本的消息队列。Redis提供了发布订阅功能(最好还是用Kafka等专业的)。
    ´分布式锁,分布式Session等。
    ´时间过期(如短信验证码的过期时间等)
     
    Redis单机环境搭建
    ´下载Redis的安装包,redis-5.0.0.tar.gz,这里安装5.0版本。
    ´拷贝到Linux下,解压:tar -zxvf redis-5.0.0.tar.gz。
    ´移动到/usr/local下(或软连接),mv redis-5.0.0 /usr/local/redis。
    ´在Redis目录执行make && make install,编译redis。
    ´修改redis.conf:

      port 7000:服务端口。

      daemonize yes:修改服务为后台运行。

      pidfile /var/run/redis_7000.pid:指定不同的pid文件。

      logfile "/var/redis/7000.log":指定log日志路径。

      dir /opt/redis-cluster/redis-7000:这个指定rdb,aof文件的路径配置。

      requirepass ibethfy:客户端访问需要密码验证。

    ´redis-server redis.conf,启动redis。
    ´redis-cli –h ip –p port –a psw,启动redis客户端。
     
    Redis数据结构和命令
    ´提供5种数据结构:字符串,哈希,列表,集合,有序集合。
     
    Redis常见全局命令
    ´keys *,查看所有键,会遍历所有键,时间复杂度为O(n)。
    ´dbsize,查看键总数,直接获取内置键总数变量,O(1)。
    ´exists key,检查键是否存在,存在返回1,不存在返回0。
    ´del key1 key2…,删除键,返回删除成功的个数。
    ´expire key second,键过期时间设置。
    ´ttl key,查看key的过期剩余时间,有就返回秒数,不会过期返回-1,不存在键返回-2。
    ´type key,返回key的数据结构。
     
    数据结构内部编码
    ´使用:object encoding key,来查看数据内部编码。3.2之后,list采用quicklist作为其内部编码,可以理解为结合linkedlist和ziplist,以ziplist为节点的linkedlist。
     
    Redis键管理命令
    ´ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
    ´linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。
    ´注意:以上两个数据结构在2版本下适用,3.2版本后,提供了quicklist内部编码,简单地说它是以一个ziplist为节点的linkedlist,它结合了ziplist和linkedlist两者的优势,为列表类型提供了一种更为优秀的内部编码实现。
    ´遍历键:keys pattern。由于该命令会遍历key,时间复杂度是O(n),如果键过多,会导致redis阻塞,所以一般不建议在生产环境中使用,若要使用,建议在其从节点执行(可能会影响主从复制)或明确key较少的情况下使用。
    ´渐进式遍历:scan的复杂度是O(1),需要多次执行才能实现keys的功能。

      scan cursor [match pattern] [count number]

      cursor是必需参数,实际上cursor是一个游标,第一次遍历从0开始,每

      次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。

      match pattern是可选参数,它的作用的是做模式的匹配,这点和keys的模式匹配很像。

      count number是可选参数,它的作用是表明每次要遍历的键个数,默认值是10,此参数可以适当增大

      scan 0 match * count 3

    ´切换数据库:select dbindex,redis默认配置的是16个数据库。
    ´flushdb:清空当前数据库数据。
    ´flushall: 清空所有数据库数据。
     
    RDB触发机制
    ´RDB持久化是把当前进程数据生成快照保存到硬盘的过程,RDB文件保存在dir配置指定的目录下,触发RDB持久化过程分为手动触发和自动触发。
    ´手动触发:save,占用主进程,阻塞;bgsave,创建子进程,阻塞发生在fork子进程阶段,很短,推荐使用。
    ´自动触发:

    1、使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。可配置多个。

    2、如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。

    3、执行debug reload命令重新加载Redis时,也会自动触发save操作。

    4、默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

    bgsave流程:

    1)执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。

    2)父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。

    3)父进程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。

    4)子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行lastsave命令可以获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项。

    5)进程发送信号给父进程表示完成,父进程更新统计信息。

    RDB优缺点

    优点

    ´RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。
    ´Redis加载RDB恢复数据远远快于AOF的方式。

    缺点

    ´RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
    ´由于触发时机问题,不适合实时持久化。
     
    AOF
    ´AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。
     
    AOF文件同步策略
    由config配置文件中appendfsync决定
    ´write操作会触发延迟写(delayed write)机制。Linux在内核提供页缓冲区用来提高硬盘IO性能。write操作在写入系统缓冲区后直接返回。同步硬盘操作依赖于系统调度机制,例如:缓冲区页空间写满或达到特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据将丢失。
    ´fsync针对单个文件操作(比如AOF文件),做强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化。
    ´问题:AOF为什么把命令追加到aof_buf中?

      Redis使用单线程响应命令,如果每次写AOF文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载。先写入缓冲区aof_buf中,还有另一个好处,Redis可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡。

    AOF重写触发机制

    ´手动触发:直接调用bgrewriteaof命令。
    ´自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机,它底层也是调用bgrewriteaof。
    ´auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB。
    ´auto-aof-rewrite-percentage:代表当前AOF文件空间(aof_current_size)和上一次重写后AOF文件空间(aof_base_size)的比值。
    ´自动触发时机=aof_current_size>auto-aof-rewrite-minsize&&(aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewritepercentage。
     
    AOF bgrewriteof流程

    1)执行AOF重写请求。

    如果当前进程正在执行AOF重写,请求不执行并返回如下响应:

    ERR Background append only file rewriting already in progress

    334

    如果当前进程正在执行bgsave操作,重写命令延迟到bgsave完成之后再

    执行,返回如下响应:

    Background append only file rewriting scheduled

    2)父进程执行fork创建子进程,开销等同于bgsave过程。

    3.1)主进程fork操作完成后,继续响应其他命令。所有修改命令依然写

    入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制正确

    性。

    3.2)由于fork操作运用写时复制技术,子进程只能共享fork操作时的内

    存数据。由于父进程依然响应命令,Redis使用“AOF重写缓冲区”保存这部

    分新数据,防止新AOF文件生成期间丢失这部分数据。

    4)子进程根据内存快照,按照命令合并规则写入到新的AOF文件。每

    次批量写入硬盘数据量由配置aof-rewrite-incremental-fsync控制,默认为

    32MB,防止单次刷盘数据过多造成硬盘阻塞。

    5.1)新AOF文件写入完成后,子进程发送信号给父进程,父进程更新

    统计信息,具体见info persistence下的aof_*相关统计。

    5.2)父进程把AOF重写缓冲区的数据写入到新的AOF文件。

    5.3)使用新AOF文件替换老文件,完成AOF重写。

     
    Redis重启加载过程
     

     集群扩容

    ´步骤:准备新节点;加入集群;迁移槽和数据;加入新节点的从节点。
    ´redis-server redis-7006.conf,新启动一个节点
    ´redis-cli –a psw --cluster add-node 127.0.0.1:7006 127.0.0.1:7000,将新节点加入集群。
    ´redis-cli –a psw –p port cluster nodes,查看集群状态,发现新加入的node作为主节点还未分配槽。
    ´redis-cli --cluster reshard 127.0.0.1:7000,通过这条命令执行槽分配。
    ´redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e,该条命令可用于将添加的新节点作为某个主节点的从节点。
    ´如果有空槽的节点已用第二步加进集群。可用以下指令来指定其主节点:
    ´redis-cli –a psw –p port; cluster replicate mastered
    ´问题:集群中主节点掉线后,会由其从节点选出一个作为新的主节点,旧主节点重新加入,会作为新主节点的从节点。
    ´问题:当一个主节点通过del-node命令移除后,它再次重启执行加入集群指令会报错,提示节点在集群中已知或存在数据。这个时候,需要先将该节点的以下数据移除:rdb文件,aof文件,cluster-config-file集群配置文件;移除文件后,重启该节点,再执行加入集群命令。
     
    集群收缩
    ´首先确认是否是主节点,如果是从节点可以直接执行下线命令。
    ´redis-cli --cluster del-node 127.0.0.1:7000 `<node-id>`
    ´如果是主节点,如果主节点没有槽,则可以执行移除直接下线。
    ´如果主节点有分配的槽,则需要将其槽分配给其他主节点,没有槽后再下线,为了保证数据的完整性。
    ´下线的主节点如果有从节点,则会分配给集群中的一个主节点作为其从节点。
     

     集群迁移

    ´1.Stop your clients. No automatic live-migration to Redis Cluster is currently possible. You may be able to do it orchestrating a live migration in the context of your application / environment.
    ´2.Generate an append only file for all of your N masters using the BGREWRITEAOF command, and waiting for the AOF file to be completely generated.
    ´3.Save your AOF files from aof-1 to aof-N somewhere. At this point you can stop your old instances if you wish (this is useful since in non-virtualized deployments you often need to reuse the same computers).
    ´4.Create a Redis Cluster composed of N masters and zero slaves. You'll add slaves later. Make sure all your nodes are using the append only file for persistence.
    ´5.Stop all the cluster nodes, substitute their append only file with your pre-existing append only files, aof-1 for the first node, aof-2 for the second node, up to aof-N.
    ´6.Restart your Redis Cluster nodes with the new AOF files. They'll complain that there are keys that should not be there according to their configuration.
    ´7.Use redis-cli --cluster fix command in order to fix the cluster so that keys will be migrated according to the hash slots each node is authoritative or not.
    ´8.Use redis-cli --cluster check at the end to make sure your cluster is ok.
    ´9.Restart your clients modified to use a Redis Cluster aware client library.
  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/ibethfy/p/10794484.html
Copyright © 2011-2022 走看看