Redis缓存数据库深入理解

1.redis基本介绍

       redis单机存量最大数据为7500万~8500万(开启redis虚拟内存功能),内存占用大约13G。相同数据模型,在13G内存下,redis保存的数据为8千万,memcached保存的数据为1亿;memcached写性能比redis性能要高;且达到内存上线时:memcached的只在临界点有点波动,而redis性能急剧下降(子进程dump数据及每秒产生大量页面错误),且CPU的利用率memcached相对稳定保持在150%,redis的CPU利用率达峰值前相对稳定在90%,之后CPU利用率直线下降。redis单线程运行,CPU利用率不高,故建议在同一个机器中部署多个redis。memcached由于是纯内存操作,故不会产生页面错误;而redis则会产生大量的页面错误。

2.redis数据持久化

      redis宕机时间段,缓存数据量大(TB),宕机恢复数据时间短(redis支持主从复制);redis数据持久化有两大分类:RDB持久化和AOF持久化。
     RDB持久化有三种实现方式:(特点—保存所有数据,资源和时间耗费太大,持久化过程数据易丢失)
    1.save 创建RDB文件(很快);
     2.bgsave 后台子进程创建RDB文件(异步创建);
     3.save time(时间维度:计数器秒) times(次数计数器)save 60 100,文件创建完成后,自动清除时间和次数计数器为0。
     AOF持久化:存储redis数据库所有操作的命令集到AOF文件中
      配置参数appendfsync — always、everysec、no,默认参数为everysec:每秒将缓存区里的命令写入到AOF文件里,即最多只丢失1秒的数据。为防止AOF体积过大,redis支持AOF文件的重写。(BGREWRITEAOF)

3.Linux-CentOS  redis安装

1.将redis-2.8.tar.gz安装包移动到/usr/software/目录下,并且解压:tar -xzvf file.tar.gz;
2.安装(redis是C语言编写)redis编译环境:yum install gcc tcl -y;
3.进入到解压的redis-2.8文件夹下执行:make 编译;
4.在redis-2.8上级目录创建redis文件夹;
5.进入到redis-2.8目录下,执行安装命令且指定安装位置/usr/software/redis/
                        make PREFIX=/usr/software/redis install
6.查看系统当前开放端口情况:ss -tanl    redis端口是否已开通;
7.将redis服务加入环境变量中:vim ~/.bash_profile;
8.加入redis的安装配置路径:
                        export REDIS_HOME=/usr/software/redis
                        export PATH=$PATH:$REDIS_HOME/bin
9.保存环境配置,执行环境配置重载命令:source ~/.bash_profile;
10.将redis做成后台服务(damon),进入到redis-2.8/utils/,执行命令:./install_server.sh;
11.重命名/etc/init.d/目录下的redis_6379为redis,执行命令:mv redis_6379 redisd即完成redis数据库的安装。

4.redis的基本特点:少量数据存储,高速读写访问

1. 支持多种数据类型:
    String——字符串类型数据存储
    List——集合数据存储        
    Set——排异集合数据存储        
    Sortedset    ——Set+跳表(score:每一个score含有一个分数,且默认根据该分数升序)
    Hash——String类型的Value值换为Map容器
2.支持简易的订阅、发布功能;通过multi开启事务,exec执行所有事物块待提交事务,discard取消之前加入事务块种的事务。
3.Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
4.Redis支持数据的持久化

    Redis支持将当前数据的快照存成一个数据文件的持久化机制,即RDB快照。但是一个持续写入的数据库如何生成快照呢?Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件。我们可以通过Redis的save指令来配置RDB快照生成的时机,比如配置10分钟就生成快照,也可以配置有1000次写入就生成快照,也可以多个规则一起实施。这些规则的定义就在Redis的配置文件中,你也可以通过Redis的CONFIG SET命令在Redis运行时设置规则,不需要重启Redis。Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的,当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件,这样在任何时候出现故障,Redis的RDB文件都总是可用的。同时,Redis的RDB文件也是Redis主从同步内部实现中的一环。RDB有他的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。在某些业务下,这是可以忍受的。
    AOF日志的全称是append only file,它是一个追加写入的日志文件。与一般数据库的binlog不同的是,AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令。只有那些会导致数据发生修改的命令才会追加到AOF文件。每一条修改数据的命令都生成一条日志,AOF文件会越来越大,所以Redis又提供了一个功能,叫做AOF rewrite。其功能就是重新生成一份AOF文件,新的AOF文件中一条记录的操作只会有一次,而不像一份老文件那样,可能记录了对同一个值的多次操作。其生成过程和RDB类似,也是fork一个进程,直接遍历数据,写入新的AOF临时文件。在写入新文件的过程中,所有的写操作日志还是会写到原来老的AOF文件中,同时还会记录在内存缓冲区中。当重完操作完成后,会将所有缓冲区中的日志一次性写入到临时文件中。然后调用原子性的rename命令用新的AOF文件取代老的AOF文件。AOF是一个写文件操作,其目的是将操作日志写到磁盘上,所以它也同样会遇到我们上面说的写操作的流程。在Redis中对AOF调用write写入后,通过appendfsync选项来控制调用fsync将其写到磁盘上的时间,下面appendfsync的三个设置项,安全强度逐渐变强。

5.redis和mamcached比较

     Memcached是一个自由开源的,高性能,分布式内存对象缓存系统,Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。
      1. Redis 和 Memcache 都是基于内存的数据存储系统。
Memcached是高性能分布式内存缓存服务;Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:string、hash(内部存储value为HashMap)、list、set、sorted set(通过额外提供一个优先级'score'的参数来为成员排序,并且是插入有序的)等数据类型的相关操作。下面我们来进行来看一下redis和memcached的区别。
      2. Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。
      3. 内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高。而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。
      4. 性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
      5. 在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。同时由于Redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个操作,直到子线程完成swap操作后才可以进行修改。当从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行批量操作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。对于一般性的业务需求,建议使用RDB的方式进行持久化,原因是RDB的开销并相比AOF日志要低很多,对于那些无法忍数据丢失的应用,建议使用AOF日志。
      6. Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。下图给出了Memcached的分布式存储实现架构。当客户端向Memcached集群发送数据之前,首先会通过内置的分布式算法计算出该条数据的目标节点,然后数据会直接发送到该节点上存储。但客户端查询数据时,同样要计算出查询数据所在的节点,然后直接向该节点发送查询请求以获取数据。相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。最新版本的Redis已经支持了分布式存储功能。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能。下图给出Redis Cluster的分布式存储架构,其中节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个key的数值域分成4096个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是4096。Redis Cluster使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。为了保证单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点都会有对应的两个用于冗余的Slave节点。这样在整个集群中,任意两个节点的宕机都不会导致数据的不可用。当Master节点退出后,集群会自动选择一个Slave节点成为新的Master节点。

猜你喜欢

转载自blog.csdn.net/u011635492/article/details/80316499