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.
posted @ 2019-04-30 10:16  ibethfy  阅读(230)  评论(0编辑  收藏  举报