云服务器

初识Redis(1)

2017-06-22 10:58:12 0

Redis简介:

Redis全称REmote DIctionary Server(Redis),是一个由Salvatore Sanfilippo写的一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型的key-value存储系统。

它通常被称为数据结构服务器,因为值(value)可以是字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

Redis 和 Memcached区别:

没有必要过多的关心性能,因为二者的性能都已经足够高了。

【核数】:由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

【结论】:无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)

内存使用率,与应用场景和使用特性有关。

【内存使用率】:如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。

【结论】:内存使用率和你的应用场景和数据特性有关。

Redis具有数据持久化和数据同步的特性。

【Redis独有数据特性】:如果你对数据持久化和数据同步有所要求,即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。

Redis支持更复杂的结构和操作。

【Redis独有数据结构和操作】:相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

【Memcache】:只支持简单的key/value数据结构

【Redis】:支持多种数据结构,如 string(字符串)、 list(双向链表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基数估算)

常用网站使用:

【Redis】:Twitter GitHub Weibo

【memcached】:Google Facebook .(几千台的memcached集群)

Redis数据持久化特性:

【算法特性】:

Redis支持Virtual Memory,可以限定内存使用大小,当数据超过阈值,则通过类似LRU的算法把内存中的最不常用数据保存到硬盘的页面文件中。

【缓存特性1】:

在Redis中,并不是所有的数据都一直存储在内存中的。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据LRU算法计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。

【缓存特性2】:

这种特性使得Redis可以保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。

【阻塞问题】:

同时由于Redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以当从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,Redis将阻塞这个操作,直到子线程完成swap操作后才可以进行修改。

结论:

所以Redis运行我们设置I/O线程池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。

Redis缓存更新机制:

【Cache Aside Pattern】:这是最常用最常用的pattern了。其具体逻辑如下:

失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。

命中:应用程序从cache中取数据,取到后返回。

更新:先把数据存到数据库中,成功后,再让缓存失效。

【错误更新方式】:

先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的

试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。

Write Behind Caching Pattern:

在更新数据的时候,只更新缓存,不更新数据库,而我们的缓存会异步地批量更新数据库。这个设计的好处就是让数据的I/O操作飞快无比(因为直接操作内存嘛 ),因为异步,write backg还可以合并对同一个数据的多次操作,所以性能的提高是相当可观的。

【问题1】:数据不是强一致性的,而且可能会丢失(我们知道Unix/Linux非正常关机会导致数据丢失,就是因为这个事)。在软件设计上,我们基本上不可能做出一个没有缺陷的设计,就像算法设计中的时间换空间,空间换时间一个道理,有时候,强一致性和高性能,高可用和高性性是有冲突的。软件设计从来都是取舍Trade-Off。

【问题2】:Write Back实现逻辑比较复杂,因为他需要track有哪数据是被更新了的,需要刷到持久层上。操作系统的write back会在仅当这个cache需要失效的时候,才会被真正持久起来,比如,内存不够了,或是进程退出了等情况,这又叫lazy write。

Read Through:

Read Through 套路就是在查询操作中更新缓存,也就是说,当缓存失效的时候(过期或LRU换出),Cache Aside是由调用方负责把数据加载入缓存,而Read Through则用缓存服务自己来加载,从而对应用方是透明的。

Write Through:

Write Through 套路和Read Through相仿,不过是在更新数据时发生。当有数据更新的时候,如果没有命中缓存,直接更新数据库,然后返回。如果命中了缓存,则更新缓存,然后再由Cache自己更新数据库(这是一个同步操作)

Redis 与 数据库处理数据的两种模式:

按照我们一般的使用Redis的场景应该是这样的:

也就是说:我们会先去redis中判断数据是否存在,如果存在,则直接返回缓存好的数据。而如果不存在的话,就会去数据库中,读取数据,并把数据缓存到Redis中。

适用场合:如果数据量比较大,但不是经常更新的情况(比如用户排行)

而第二种Redis的使用,跟第一种的情况完成不同,具体的情况请看:

这里我们会先去redis中判断数据是否存在,如果存在,则直接更新对应的数据(这一步会把对应更新过的key记录下来,比如也保存到redis中比如:key为:save_update_keys【用lpush列表记录】),并把更新后的数据返回给页面。而如果不存在的话,就会去先更新数据库中内容,然后把数据保存一份到Redis中。后面的工作:后台会有相关机制把Redis中的save_update_keys存储的key,分别读取出来,找到对应的数据,更新到DB中。

【优点】:这个流程的主要目的是把Redis当作数据库使用,更新获取数据比DB快。非常适合大数据量的频繁变动(比如微博)。

【缺点】:对Redis的依赖很大,要做好宕机时的数据保存。

【难点】:在前期规划key的格式,存储类型很重要,因为这会影响能否把数据同步到DB。

来自 <http://www.veryhuo.com/a/view/9266.html>

redis安装:

到官网下载安装包redis-2.6.14-tar.gz,移至/usr/local/src

到源码目录下直接make,因为有makefile文件,不需要./configure

将主要目录移到业务环境目录

【redis-server】:Redis服务器的daemon启动程序

【redis-cli】:Redis命令行操作工具。

【redis-sentinel】:Redis实例的监控管理、通知和实例失效备援服务管理工具

【redis-benchmark】:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能。

【redis-check-dump】:数据库检测工具

【redis-check-aof】:日志更新检测工具

【redis.conf】:redis配置文件

形如:cp /usr/local/src/redis-3.2.6/redis.conf /usr/local/myredis/

将redis的server移至后台运行,即将redis.conf配置文件中的daemonize设置为yes;同时打开客户端,进行相关操作后会在redis目录下生成dump.rdb同步文件,里面存放key和value文件:

./redis-cli -h 127.0.0.1 -p 6379

set huangbin silence

get huangbin

【PHP操作redis】:

【安装redis模块】:

下载phpredis并进行解压:

tar xf nicolasff-phpredis-2.1.3-168-g8ebb811.tar.gz -C /usr/local/src/

在解压文件下执行指令,生成./configure文件;该命令用phpize给PHP动态添加扩展

/usr/local/php/bin/phpize

执行./configure关联php

./configure --with-php-config=/usr/local/php/bin/php-config

在/etc/php.ini中的extension_dir下面加入

extension=redis.so

重启apache,打开phpinfo出现redis模块表示成功

【执行php文件】:

上一篇: 无

微信关注

获取更多技术咨询