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.
  • 相关阅读:
    523 vue组件化高级 插槽slot:slot基本使用,具名插槽,编译作用域,作用域插槽
    522 vue父子组件的访问方式: $children、$refs、$parent
    521 vue子组件向父组件传递数据
    520 vue父组件向子组件传递:props基本用法,props数据验证,props中的驼峰标识
    在 React 组件中使用 Refs 指南
    Flutter 代码开发规范
    Angular ZoneJS 原理
    vue中$refs, $emit, $on, $once, $off的使用
    详解Js加法运算符
    JavaScript 异常
  • 原文地址:https://www.cnblogs.com/ibethfy/p/10794484.html
Copyright © 2011-2022 走看看