大型网站架构设计-Redis 高性能的key-value数据库

2014-12-19 13:10:37     74 人阅读    

         Redis是一个高性能的key-value数据库,与其他很多key-value数据库的不同之处在于,Redis 不仅支持简单的键值对类型的存储,还支持其他一系列丰富的数据存储结构,包括strings、 hashs、lists、sets、sorted sets等,并在这些数据结构类型上定义了一套强大的API。通过定义 不同的存储结构,Redis可以很轻易地完成很多其他key-value数据库难以完成的任务,如排序、去重等。
安装 Redis
下载Redis源码安装包:

wget http://download.redis.io/releases/redis-2.8.8.tar.gz
19关于HBase的二级索弓|表,华为提供了 hindex的二级索弓|解决方案,有兴趣的读者可以参考 https://github.com/Huawei-Hadoop/hindex。
longlong@ubuntu:~$ wget http://download.redls.to/releases/redls-2.8.8.tar.gz ••2014-04-06 00:05:22-- http://download.recKs.io/releases/recRs-2.8.8.tar.gz Resolving download.redls.io (download.redls.to)... 109.74.203.151 Connecting to download.redls.io (download.redls.io)|109.74.203.151|:80... conne< ted.
HTTP request sent, awaiting response... 200 OK Length: 1073450 (1.0M) [applicatlon/x-gzlp]
Saving to: 'redls-2.8.8.tar.gz'
19% [======> ] 214,588 3.96K/S eta 4n 2s |


解压文件:
tar -xf redis-2.8.8.tar.gz


编译安装Redis:
sudo make PREFIX=/usr/l〇cal/redis install


将Redis安装到/usr/local/redis目录,然后,从安装包中找到Redis的配置文件,将其复制
到安装的根目录。
sudo cp redis.conf /usr/local/redis/


启动 Redis Server:

./redis-server ../redis.conf
longlong@ubuntu:/usr/local/redis/bin$ ./redls-server ../redls.conf [6535] 06 Apr 00:24:37.800 # You requested naxclients of 10000 requiring at leasj t 10032 max file descriptors.
[6535] 06 Apr 00:24:37.802 # Redis can't set naximun open files to 10032 becausej of OS error: Operation not permitted.
[6535] 06 Apr 00:24:37.802 # Current maximum open files is 1024. naxclients has been reduced to 4064 to compensate for low ulinit. If you need higher naxclients increase 'ulimit -n'.
[6535] 06 Apr 00:24:37.803 # Warning: 32 bit instance detected but no memory llnj it set. Setting 3 GB naxnenory limit with 'noeviction' policy now.
Redls 2.8.8 (00000000/0) 32 bit
Running in stand alone node Port: 6379 PID: 6535
http://redis.lo
使用redis-cli进行访问  : ./redis-cli


longlong@ubuntu:/usr/local/redis/bln$ ./redls-cll
0.1:6379> set name chenkangxian OK
0.1:6379> get name "chenkangxian"
0.1:6379>

使用 Redis API
Redis的Java client21有很多,这里选择比较常用的Jedis22来介绍Redis数据访问的API。 首先,需要对Redis client进行初始化:
Jedis redis = new Jedis ("192.168.136.135",6379);
Redis支持丰富的数据类型,如strings、hashs、lists、sets、sorted sets等,这些数据类型都
有对应的API来进行操作。比如,Redis的strings类型实际上就是最基本的key-value形式的数 据,一个key对应一个value,它支持如下形式的数据访问:
redis.set("name", "chenkangxian");//设置 key-value redis.setex(”content”,5, "hello”);//设置 key-value 有效期为 5 秒
redis.mset(”class”,”a”,”age”,”25”); //—次设置多个 key-value redis.append(”content”," lucy");//给字符串追加内容 String content = redis.get("content"); //根据 key 获取 value List<String> list = redis.mget(”class”,”age”);//-次取多个 key
通过set方法,可以给对应的key设值;通过get方法,可以获取对应key的值;通过setex 方法可以给key-value设置有效期;通过mset方法,一次可以设置多个key-value对;通过mget 方法,可以一次获取多个key对应的value,这样的好处是,可以避免多次请求带来的网络开销, 提高性能;通过append方法,可以给已经存在的key对应的value后追加内容。


Redis的hashs实际上是一个string类型的field和value的映射表,类似于Map,特别适合 存储对象。相较于将每个对象序列化后存储,一个对象使用hashs存储将会占用更少的存储空 间,并且能够更为方便地存取整个对象:

redis.hset("url", "google", "www.google.cn");//给 Hash 添加 key-value redis.hset("url", "taobao", "www.taobao.com"); redis.hset("url", "sina", "www.sina.com.cn");
Map<String,String> map = new HashMap<String,String>(); map.put("name", "chenkangxian"); map.put("sex", "man"); map.put("age", "100");
redis.hmset("userinfo", map);//批量设置值
String name = redis.hget("userinfo", "name");//取 Hash 中某个 key 的值 //取Hash的多个key的值
List<String> urllist = redis.hmget("url","google","taobao","sina");
//取Hash的所有key的值
Map<String,String> userinfo = redis.hgetAll("userinfo");

通过hset方法,可以给一个Hash存储结构添加key-value数据;通过hmset方法,能够一 次性设置多个值,避免多次网络操作的开销;使用hget方法,能够取得一个Hash结构中某个 key对应的value;使用hmget方法,则可以一次性获取得多个key对应的value;通过hgetAll 方法,可以将Hash存储对应的所有key-value —次性取出。
Redis的lists是一个链表结构,主要的功能是对元素的push和pop,以及获取某个范围内 的值等。push和pop操作可以从链表的头部或者尾部插入/删除元素,这使得lists既可以作为栈 使用,又可以作为队列使用,其中,操作的key可以理解为链表的名称:

redis.lpush(”charlist”,"abc");//在 list 首部添加元素 redis.lpush("charlist", "def");
redis.rpush("charlist", "hij");//在 list 尾部添加元素 redis.rpush("charlist", "klm");
List<String> charlist = redis.lrange("charlist", 0, 2); redis.lpop("charlist");//在 list 首部删除兀素 redis.rpop("charlist");//在 list 尾部删除兀素
Long charlistSize = redis.llen("charlist");//获得 list 的大小


通过lpush和rpush方法,分别可以在list的首部和尾部添加元素;使用lpop和rpop方法,
可以在list的首部和尾部删除元素,通过lrange方法,可以获取list指定区间的元素。
Redis的sets与数据结构的set相似,用来存储一个没有重复元素的集合,对集合的元素可 以进行添加和删除的操作,并且能够对所有元素进行枚举:

redis.sadd("SetMem", "s1");//给 set 添加元素 redis.sadd("SetMem", "s2"); redis.sadd("SetMem", "s3"); redis.sadd("SetMem", "s4"); redis.sadd("SetMem", "s5");
redis.srem("SetMem", "s5");//从 set 中移除元素
Set<String> set = redis.smembers("SetMem") ;//枚举出 set 的元素

sadd方法用来给set添加新的元素,而srem则可以对元素进行删除,通过smembers方法,
能够枚举出set中的所有元素。
sorted sets是Redis sets的一个升级版本,它在sets的基础之上增加了一个排序的属性,该 属性在添加元素时可以指定,sorted sets将根据该属性来进行排序,每次新元素增加后,sorted sets会重新对顺序进行调整。sorted sets不仅能够通过range正序对set取值,还能够通过range 对set进行逆序取值,极大地提高了 set操作的灵活性:

"5th");//插入sort set,并指定元素的序号 "4th");
"3th");
"2th");
"1th");
//根据范围取 set
Set<String> sortset = redis.zrange("SortSetMem", 2, 4);
//根据范围反向取 set
Set<String> revsortset = redis.zrevrange(nSortSetMem", 1, 2);


         通过zadd方法来给sorted sets新增元素,在新增操作的同时,需要指定该元素排序的序号, 以便进行排序。使用zrange方法可以正序对set进行范围取值,而通过zrevrange方法,则可以 高效率地逆序对set进行范围取值。


         相较于传统的关系型数据库,Redis有更好的读/写吞吐能力,能够支撑更高的并发数。而 相较于其他的key-value类型的数据库,Redis能够提供更为丰富的数据类型的支持,能够更灵 活地满足业务需求。Redis能够高效率地实现诸如排序取topN、访问计数器、队列系统、数据 排重等业务需求,并且通过将服务器设置为cache-only,还能够提供高性能的缓存服务。相较 于memcache来说,在性能差别不大的情况下,它能够支持更为丰富的数据类型。

本文出自   《大型分布式网站架构设计与实践试读样章》 试读,如果感觉到对你有帮助可以去购买该书


原文地址:http://www.itmmd.com/201412/345.html
该文章由 萌萌的IT人 整理发布,转载须标明出处。

大型网站架构设计-消息系统ActiveMQ &JMS (1)   上一篇
下一篇  产品经理学习笔记(10)-到用户中去:找到你的核心用户

精彩回复
发表评论
姓名:       

《程序员app》专门为程序员量身定做!