redis 总结与应用

url: http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html
url: http://www.infoq.com/cn/articles/tq-why-choose-redis
url: http://www.tuicool.com/articles/ERJFRvy
url: http://blog.nosqlfan.com/html/320.html
url: http://blog.csdn.net/jiangguilong2000/article/details/24143721
url: http://code.google.com/p/redis/wiki/TwitterAlikeExample #做者在wiki中给出了一个很是好的例子,以使咱们能够快速上手
url: http://labs.alcacoop.it/doku.php?id=articles:redis_land #另外一个redis教程
url: http://www.rediscookbook.org/ #一个redis爱好者建立的相关问题讨论网站
url: http://www.infoq.com/cn/articles/tq-why-choose-redis #为何使用 Redis及其产品定位
url: http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage #Redis内存使用优化与存储php


1.redis 安装
下载官网:http://code.google.com/p/redis/downloads/listhtml

2.redis-benchmark 官网:http://code.google.com/p/redis/wiki/Benchmarks
新官网:http://redis.io/mysql

例以下载 redis-2.6.14.tar.gz
命令:tar -xzvf redis-2.6.14.tar.gz
命令:cd redis-2.6.14
命令:make
命令:cd src && make installweb

安装完毕!
make命令执行完成后,会在当前目录下生成本个可执行文件,至少有 redis-server、redis-cli、redis-benchmark
redis-server:Redis服务器的daemon启动程序
redis-cli:Redis命令行操做工具。固然,你也能够用telnet根据其纯文本协议来操做
redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能redis

在安装包中找到 redis.conf 修改其中的参数:
daemonize: 是否之后台daemon方式运行
pidfile: pid文件位置
port: 监听的端口号
timeout: 请求超时时间
loglevel: log信息级别
logfile: log文件位置
databases: 开启数据库的数量
save * *: 保存快照的频率,第一个*表示多长时间,第三个*表示执行多少次写操做。在必定时间内执行必定数量的写操做时,自动保存快照。可设置多个条件。
rdbcompression:是否使用压缩
dbfilename: 数据快照文件名(只是文件名,不包括目录)
dir: 数据快照的保存目录(这个是目录)
appendonly: 是否开启appendonlylog,开启的话每次写操做会记一条log,这会提升数据抗风险能力,但影响效率。
appendfsync:appendonlylog 如何同步到磁盘(三个选项,分别是每次写都强制调用fsync、每秒启用一次fsync、不调用fsync等待系统本身同步)
这边给一份例子(提供参考)
daemonize yes
pidfile /usr/local/redis/var/redis.pid
port 6379
timeout 300
loglevel debug./
logfile /usr/local/redis/var/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /usr/local/redis/var/
appendonly no
appendfsync always
glueoutputbuf yes
shareobjects no
shareobjectspoolsize 1024sql

启动服务,命令: /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
链接到你的redis服务,命令: telnet 127.0.0.1 6379mongodb


3.简单使用redis (找到 src 文件夹)
命令: ./redis-server ../redis.conf
解释:启动redis服务数据库

命令: ./redis-cli
解释:另外开一个终端,链接redis服务json

命令: (redis>) set name helloword!
解释:链接上redis服务后, 在命令框中输入数据操做命令; 设置 name 的值为 "helloword!"服务器

命令: get name
解释:获得name的值, 正常状况获得 "helloword!"


4.简单使用 redis benchmark
Redis-benchmark为Redis性能测试工具
指令说明:
Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]

-h <hostname> Server hostname (default 127.0.0.1)
-p <port> Server port (default 6379)
-s <socket> Server socket (overrides host and port)
-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 10000)
-d <size> Data size of SET/GET value in bytes (default 2)
-k <boolean> 1=keep alive 0=reconnect (default 1)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
Using this option the benchmark will get/set keys in the form mykey_rand:000000012456 instead of constant keys, the <keyspacelen> argument determines the max number of values for the random number. For instance if set to 10 only rand:000000000000 - rand:000000000009 range will be allowed.
-P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
-q Quiet. Just show query/sec values 只显示每秒钟能处理多少请求数结果
--csv Output in CSV format
-l Loop. Run the tests forever 永久测试
-t <tests> Only run the comma separated list of tests. The test names are the same as the ones produced as output.
-I Idle mode. Just open N idle connections and wait.

实例:
命令: redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100
解释: SET/GET 100 bytes 检测host为127.0.0.1 端口为6379的redis服务器性能

命令: redis-benchmark -h 127.0.0.1 -p 6379 -c 5000 -n 100000
解释: 5000个并发链接,100000个请求,检测host为127.0.0.1 端口为6379的redis服务器性能

命令: redis-benchmark -n 100000 -c 60
解释: 向redis服务器发送100000个请求,每一个请求附带60个并发客户端

命令: redis-benchmark -h localhost -p 6379 -c 100 -n 100000
解释: 100个并发链接,100000个请求,检测host为localhost 端口为6379的redis服务器性能

命令: redis-cli -h localhost -p 6380 monitor
解释: Dump all the received requests in real time; 监控host为localhost,端口为6380,redis的链接及读写操做

命令: redis-cli -h localhost -p 6380 info
解释: Provide information and statistics about the server ; 提供host为localhost,端口为6380,redis服务的统计信息


4.redis简介
redis的代码遵循ANSI-C编写,能够在全部POSIX系统(如Linux,BSD, Mac OS X, Solaris等)上安装运行。并且Redis并不依赖任何非标准库,也没有编译参数必需添加。redis的安装出奇的简单。
redis 由四个可执行文件:redis-benchmark、redis-cli、redis-server、redis-stat?这四个文件,加上一个redis.conf就构成了整个redis的最终可用包。它们的做用以下:
1> redis-server:Redis服务器的daemon启动程序
2> redis-cli:Redis命令行操做工具。固然,你也能够用telnet根据其纯文本协议来操做
3> redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能
4> redis-stat:Redis状态检测工具,能够检测Redis当前状态参数及延迟情况

为何使用 redis
传统MySQL + Memcached架构遇到的问题
实际MySQL是适合进行海量数据存储的,经过Memcached将热点数据加载到cache,加速访问,不少公司都曾经使用过这样的架构,但随着业务数据量的不断增长,和访问量的持续增加,咱们遇到了不少问题:
1.MySQL须要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工做占据大量开发时间。
2.Memcached与MySQL数据库数据一致性问题。
3.Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL没法支撑。
4.跨机房cache同步问题。

业界不断涌现出不少各类各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是咱们须要深刻研究和思考的问题,实际归根结底最重要的是了解这些产品的定位,而且了解到每款产品的tradeoffs,在实际应用中作到扬长避短,整体上这些NoSQL主要用于解决如下几种问题
1.少许数据存储,高速读写访问。此类产品经过数据所有in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。
2.海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。
3.这方面最具表明性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个彻底无中心的设计,节点之间经过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,经过相似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,而后按期compat归并到磁盘上,将随机写优化为顺序写,提升写入性能。
4.Schema free,auto-sharding等。好比目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,而且支持auto-sharding等功能,好比mongodb。
面对这些不一样类型的NoSQL产品,咱们须要根据咱们的业务场景选择最合适的产品。

redis适用场景,如何正确的使用
前面已经分析过,Redis最适合全部数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差异,那么可能你们就会有疑问,彷佛Redis更像一个增强版的Memcached,那么什么时候使用Memcached,什么时候使用Redis呢?
Redis与Memcached的比较
1.网络IO模型
Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络链接,接受请求后,将链接描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型能够发挥多核做用,可是引入了cache coherency和锁的问题,好比,Memcached最经常使用的stats 命令,实际Memcached全部操做都要对这个全局变量加锁,进行计数等工做,带来了性能损耗。
Redis 使用单线程的IO复用模型,本身封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,对于单纯只有IO操做来讲,单线程能够将速度优点发挥到最大,可是Redis也提供了一些简单的计算功能,好比排序、聚合等,对于这些操做,单线程模型实际会严重影响总体吞吐量,CPU计算过程当中,整个IO调度都是被阻塞住的。

2.内存管理方面
Memcached使用预分配的内存池的方式,使用slab和大小不一样的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式能够省去申请/释放内存的开销,而且能减少内存碎片产生,但这种方式也会带来必定程度上的空间浪费,而且在内存仍然有很大空间时,新的数据也可能会被剔除,缘由能够参考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/
Redis使用现场申请内存的方式来存储数据,而且不多使用free-list等方式来优化内存分配,会在必定程度上存在内存碎片,Redis跟据存储命令参数,会把带过时时间的数据单独存放在一块儿,并把它们称为临时数据,非临时数据是永远不会被剔除的,即使物理内存不够,致使swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合做为存储而不是cache。

3.数据一致性问题
Memcached提供了cas命令,能够保证多个并发访问操做同一份数据的一致性问题。 Redis没有提供cas 命令,并不能保证这点,不过Redis提供了事务的功能,能够保证一串 命令的原子性,中间不会被任何操做打断。

4.存储方式及其它方面
Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能
Redis除key/value以外,还支持list,set,sorted set,hash等众多数据结构,提供了KEYS进行枚举操做,但不能在线上使用,若是须要枚举线上数据,Redis提供了工具能够直接扫描其dump文件,枚举出全部数据,Redis还同时提供了持久化和复制等功能。

5.关于不一样语言的客户端支持
在不一样语言的客户端方面,Memcached和Redis都有丰富的第三方客户端可供选择,不过由于Memcached发展的时间更久一些,目前看在客户端支持方面,Memcached的不少客户端更加成熟稳定,而Redis因为其协议自己就比Memcached复杂,加上做者不断增长新的功能等,对应第三方客户端跟进速度可能会赶不上,有时可能须要本身在第三方客户端基础上作些修改才能更好的使用。根据以上比较不难看出,当咱们不但愿数据被踢出,或者须要除key/value以外的更多数据类型时,或者须要落地功能时,使用Redis比使用Memcached更合适。

关于Redis的一些周边功能
Redis除了做为存储以外还提供了一些其它方面的功能,好比聚合计算、pubsub、scripting等,对于此类功能须要了解其实现原理,清楚地了解到它的局限性后,才能正确的使用,好比pubsub功能,这个实际是没有任何持久化支持的,消费方链接闪断或重连之间过来的消息是会所有丢失的,又好比聚合计算和scripting等功能受Redis单线程模型所限,是不可能达到很高的吞吐量的,须要谨慎使用。总的来讲Redis做者是一位很是勤奋的开发者,能够常常看到做者在尝试着各类不一样的新鲜想法和思路,针对这些方面的功能就要求咱们须要深刻了解后再使用。

总结:
1.Redis使用最佳方式是所有数据in-memory。
2.Redis更多场景是做为Memcached的替代者来使用。
3.当须要除key/value以外的更多数据类型支持时,使用Redis更合适。
当存储的数据不能被剔除时,使用Redis更合适。

关于做者
田琪,目前负责新浪微博平台底层架构与研发工做,以前曾担任搜狐白社会实时游戏平台核心架构工做,主要关注webgame, 分布式存储,nosql 和 erlang 等领域,目前主要从事mysql源代码的一些深刻研究工做,浪微博:?http://weibo.com/bachmozart。

附:redis命令列表: 链接控制 QUIT 关闭链接 AUTH (仅限启用时)简单的密码验证 适合全体类型的命令 EXISTS key 判断一个键是否存在;存在返回 1;不然返回0; DEL key 删除某个key,或是一系列key;DEL key1 key2 key3 key4 TYPE key 返回某个key元素的数据类型( none:不存在,string:字符,list,set,zset,hash) KEYS pattern 返回匹配的key列表(KEYS foo*:查找foo开头的keys) RANDOMKEY 随机得到一个已经存在的key,若是当前数据库为空,则返回空字符串 RENAME oldnamenewname 更改key的名字,新键若是存在将被覆盖 RENAMENX oldnamenewname 更改key的名字,若是名字存在则更改失败 DBSIZE 返回当前数据库的key的总数 EXPIRE 设置某个key的过时时间(秒),(EXPIRE bruce1000:设置bruce这个key1000秒后系统自动删除)注意:若是在尚未过时的时候,对值进行了改变,那么那个值会被清除。 TTL 查找某个key还有多长时间过时,返回时间秒 SELECT index 选择数据库 MOVE key dbindex 将指定键从当前数据库移到目标数据库 dbindex。成功返回1;不然返回0(源数据库不存在key或目标数据库已存在同名key); FLUSHDB 清空当前数据库中的全部键 FLUSHALL 清空全部数据库中的全部键 处理字符串的命令 SET key value 给一个键设置字符串值。SET keyname datalength data (SET bruce 10paitoubing:保存key为burce,字符串长度为10的一个字符串paitoubing到数据库),data最大不可超过1G。 GET key 获取某个key的value值。如key不存在,则返回字符串“nil”;如key的值不为字符串类型,则返回一个错误。 GETSET keyvalue 能够理解成得到的key的值而后SET这个值,更加方便的操做 (SET bruce 10paitoubing,这个时候须要修改bruce变成1234567890并获取这个之前的数据paitoubing,GETSETbruce 10 1234567890) MGET key1 key2 … keyN 一次性返回多个键的值 SETNX key value SETNX与SET的区别是SET能够建立与更新key的value,而SETNX是若是key不存在,则建立key与value数据 MSET key1 value1 key2value2 … keyN valueN 在一次原子操做下一次性设置多个键和值 MSETNX key1 value1 key2value2 … keyN valueN 在一次原子操做下一次性设置多个键和值(目标键不存在状况下,若是有一个以上的key已存在,则失败) INCR key 自增键值 INCRBY key integer 令键值自增指定数值 DECR key 自减键值 DECRBY key integer 令键值自减指定数值 处理 lists 的命令 RPUSH key value 从 List尾部添加一个元素(如序列不存在,则先建立,如已存在同名Key而非序列,则返回错误) LPUSH key value 从 List头部添加一个元素 LLEN key 返回一个 List的长度 LRANGE key startend 从自定的范围内返回序列的元素 (LRANGE testlist 0 2;返回序列testlist前0 1 2元素) LTRIM key startend 修剪某个范围以外的数据 (LTRIM testlist 0 2;保留0 1 2元素,其他的删除) LINDEX keyindex 返回某个位置的序列值(LINDEX testlist 0;返回序列testlist位置为0的元素) LSET key indexvalue 更新某个位置元素的值 LREM key count value 从List的头部(count正数)或尾部(count负数)删除必定数量(count)匹配value的元素,返回删除的元素数量。 LPOP key 弹出 List的第一个元素 RPOP key 弹出 List的最后一个元素 RPOPLPUSH srckey dstkey 弹出 _srckey_ 中最后一个元素并将其压入 _dstkey_头部,key不存在或序列为空则返回“nil” 处理集合(sets)的命令(有索引无序序列) SADD keymember 增长元素到SETS序列,若是元素(membe)不存在则添加成功 1,不然失败 0;(SADD testlist 3 \none) SREM key member 删除SETS序列的某个元素,若是元素不存在则失败0,不然成功 1(SREM testlist 3 \N one) SPOP key 从集合中随机弹出一个成员 SMOVE srckey dstkeymember 把一个SETS序列的某个元素 移动到 另一个SETS序列 (SMOVE testlist test 3\ntwo;从序列testlist移动元素two到 test中,testlist中将不存在two元素) SCARD key 统计某个SETS的序列的元素数量 SISMEMBER key member 获知指定成员是否存在于集合中 SINTER key1 key2 … keyN 返回 key1, key2, …, keyN 中的交集 SINTERSTORE dstkey key1key2 … keyN 将 key1, key2, …, keyN 中的交集存入 dstkey SUNION key1 key2 … keyN 返回 key1, key2, …, keyN 的并集 SUNIONSTORE dstkey key1key2 … keyN 将 key1, key2, …, keyN 的并集存入 dstkey SDIFF key1 key2 … keyN 依据 key2, …, keyN 求 key1 的差集。官方例子: key1 = x,a,b,c key2 = c key3 = a,d SDIFF key1,key2,key3=> x,b SDIFFSTORE dstkey key1key2 … keyN 依据 key2, …, keyN 求 key1 的差集并存入 dstkey SMEMBERS key 返回某个序列的全部元素 SRANDMEMBER key 随机返回某个序列的元素 处理有序集合(sorted sets)的命令 (zsets) ZADD key score member 添加指定成员到有序集合中,若是目标存在则更新score(分值,排序用) ZREM key member 从有序集合删除指定成员 ZINCRBY key incrementmember 若是成员存在则将其增长_increment_,不然将设置一个score为_increment_的成员 ZRANGE key start end 返回升序排序后的指定范围的成员 ZREVRANGE key start end 返回降序排序后的指定范围的成员 ZRANGEBYSCORE key minmax 返回全部符合score >= min和score <=max的成员 ZCARD key 返回有序集合的元素数量 ZSCORE key element 返回指定成员的SCORE值ZREMRANGEBYSCORE key min max 删除符合 score >= min 和score <= max 条件的全部成员 排序(List, Set, Sorted Set) SORT key BY patternLIMIT start end GET pattern ASC|DESC ALPHA 按照指定模式排序集合或List SORT mylist 默认升序 ASC SORT mylist DESC SORT mylist LIMIT 0 10 从序号0开始,取10条 SORT mylist LIMIT 0 10 ALPHA DESC 按首字符排序 SORT mylist BYweight_* SORT mylist BY weight_* GET object_* SORT mylist BY weight_* GET object_* GET SORT mylist BY weight_*STORE resultkey 将返回的结果存放于resultkey序列(List) 持久控制 SAVE 同步保存数据到磁盘 BGSAVE 异步保存数据到磁盘 LASTSAVE 返回上次成功保存到磁盘的Unix时间戳 SHUTDOWN 同步保存到服务器并关闭Redis 服务器(SAVE+QUIT) BGREWRITEAOF 当日志文件过长时重写日志文件 远程控制命令 INFO 提供服务器的信息和统计信息 MONITOR 实时输出全部收到的请求 SLAVEOF 修改复制选项

相关文章
相关标签/搜索