二、Redis
1.简介
2008 年,意大利的一家创业公司 Merzia 推出了一款基于 MySQL 的网站实时统计系统
LL00GG, 然而没过多久该公司的创始人 Salvatore Sanfilippo 便对 MySQL 的性能感到失望,
于是他决定亲自为 LL00GG 量身定做一个数据库,并于 2009 年开发完成,这个数据库就是
Redis。不过 SalvatoreSanfilippo 并不满足只将 Redis 用于 LL00GG 这一款产品,而是希望更
多的人使用它,于是在同一年 Salvatore Sanfilippo 将 Redis 开源发布,并开始和 Redis 的另
一名主要的代码贡献者 Pieter Noordhuis 一起继续着 Redis 的开发,直到今天。Salvatore
Sanfilippo 自己也没有想到,短短的几年时间,Redis 就拥有了庞大的用户群体。Hacker News
在 2012 年发布了一份数据库的使用情况调查,结果显示有近 12%的公司在使用 Redis。国内如
新浪微博、街旁网、知乎网,国外如 GitHub、Stack Overflow、Flickr 等都是 Redis 的用户。
VMware 公司从 2010 年开始赞助 Redis 的开发,Salvatore Sanfilippo 和 Pieter Noordhuis
也分别 在 3 月和 5 月加入 VMware,全职开发 Redis。
2.什么是 Redis
Redis 是用 C 语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种
键值数据类型来适应不同场景下的存储需求,目前为止 Redis 支持的键值数据类型如下:
? 字符串类型
? 散列类型
? 列表类型
? 集合类型
? 有序集合类型。
官方提供测试数据: 50 个并发执行 100000 个请求,读的速度是 110000 次/s,写的速度是
81000 次/s。数据仅供参考,根据服务器配置会有不同结果。
3.redis 的应用场景
? 缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
? 聊天室的在线好友列表。
? 任务队列。(秒杀、抢购、12306 等等)
? 应用排行榜。
? 网站访问统计。
? 数据过期处理(可以精确到毫秒)
? 分布式集群架构中的 session 分离。
4.redis 在 Linux 上的安装
? 安装 redis 编译的 c 环境,yum install gcc-c++
? 将 redis-2.6.16.tar.gz 上传到 Linux 系统中
? 解压到/usr/local 下 tar -xvf redis-2.6.16.tar.gz -C /usr/local
? 进入 redis-2.6.16 目录 使用 make 命令编译 redis
? 在 redis-2.6.16 目录中 使用 make PREFIX=/usr/local/redis install 命令安装 redis
到/usr/local/redis 中
? 拷贝 redis-2.6.16 中的 redis.conf 到安装目录 redis 中
? 启动 redis 在 bin 下执行命令 redis-server redis.conf
? 如需远程连接 redis,需配置 redis 端口 6379 在 linux 防火墙中开发
/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
/etc/rc.d/init.d/iptables save
5.启动 redis
1)启动后看到如上欢迎页面,但此窗口不能关闭,窗口关闭就认为 redis 也关闭了(类 似
Tomcat 通过 bin 下的 startup.bat 的方式)
解决方案:可以通过修改配置文件 配置 redis 后台启动,即服务器启动了但不会穿件控制
台窗口
将 redis.conf 文件中的 daemonize 从 false 修改成 true 表示后台启动
2)使用命令查看 6379 端口是否启动 ps -ef | grep redis
6.Redis 的 key-value
1)redis 是一种高级的 key-value 的存储系统
2)其中的 key 是字符串类型,尽可能满足如下几点:
1>key 不要太长,最好不要操作 1024 个字节,这不仅会消耗内存还会降低查找效率
2>key 不要太短,如果太短会降低 key 的可读性3>在项目中,key 最好有一个统一的命名规范(根据企业的需求)
4>其中 value 支持五种数据类型:
? 字符串型 string
? 字符串列表 lists
? 字符串集合 sets
? 有序字符串集合 sorted sets
? 哈希类型 hashs(map)
我们对 Redis 的学习,主要是对数据的存储,下面将来学习各种 Redis 的数据类型的 存储操做:
7.存储字符串 string
字符串类型是 Redis 中最为基础的数据存储类型,它在 Redis 中是二进制安全的,这便意味
着该类型可以接受任何格式的数据,如 JPEG 图像数据或 Json 对象描述信息等。 Redis 中字
符串类型的 Value 最多可以容纳的数据长度是 512M
1)set key value:设定 key 持有指定的字符串 value,如果该 key 存在则进行覆盖操作。总是返
回”OK”
2)get key:获取 key 的 value。如果与该 key 关联的 value 不是 String 类型,redis 将返回
错误信息,因为 get 命令只能用于获取 String value;如果该 key 不存在,返 回 null。
3)getset key value:先获取该 key 的值,然后在设置该 key 的值。
4)incr key:将指定的 key 的 value 原子性的递增 1.如果该 key 不存在,其初始值为 0 , 在
incr 之后其值为 1。如果 value 的值不能转成整型,如 hello,该操作将执 行失败并返回相应
的错误信息。
5)decr key:将指定的 key 的 value 原子性的递减 1.如果该 key 不存在,其初始值 为 0,
在 incr 之后其值为-1。如果 value 的值不能转成整型,如 hello,该操作将执 行失败并返回
相应的错误信息。
6)incrby key increment:将指定的 key 的 value 原子性增加 increment,如果该key 不 存
在,器初始值为 0,在 incrby 之后,该值为 increment。如果该值不能转成 整型,如 hello
则失败并返回错误信息
7)decrby key decrement:将指定的 key 的 value 原子性减少 decrement,如果该 key 不
存在,器初始值为 0,在 decrby 之后,该值为 decrement。如果该值不能 转成整型,如 hello
则失败并返回错误信息
8)append key value:如果该 key 存在,则在原有的 value 后追加该值;如果该 key存在,
则重新创建一个 key/value
8.存储 lists 类型
在 Redis 中,List 类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,
我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis 将为
该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据
库中删除。List 中可以包含的最大元素数量是 4294967295(2^32 -1)。Integer=2^31 -1,从
元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效
的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而需要说明的
是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。相信对于有良好数据结
构基础的开发者而言,这一点并不难理解。
1)lpush key value1 value2...:在指定的 key 所关联的 list 的头部插入所有的 values,如果该
key 不存在,该命令在插入的之前创建一个与该 key 关联的空链表,之后再向该链表的头部插入
数据。插入成功,返回元素的个数。
2)rpush key value1、value2…:在该 list 的尾部添加元素
3)lrange key start end:获取链表中从 start 到 end 的元素的值,start、end 可为负数,若为
-1 则表示链表尾部的元素,-2 则表示倒数第二个,依次类推…
4)lpushx key value:仅当参数中指定的 key 存在时(如果与 key 管理的 list 中没有值时,则该
key 是不存在的,只能 push 一个元素)在指定的 key 所关联的 list 的头部插入 value。
5)rpushx key value:在该 list 的尾部添加元素
6)lpop key:返回并弹出指定的 key 关联的链表中的第一个元素,即头部元素。
7)rpop key:从尾部弹出元素。
8)rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部
9)llen key:返回指定的 key 关联的链表中的元素的数量。
10)lset key index value(修改):设置链表中的 index 的脚标的元素值,0 代表链表的头元素,
-1 代表链表的尾元素。
11)lrem key count value(删除):删除 count 个值为 value 的元素,如果 count 大于 0,从头向尾遍历并删除 count 个值为 value 的元素,如果 count 小于 0,则从尾向头遍历并删除。
如果 count 等于 0,则删除链表中所有等于 value 的元素。
12)linsert key before|after pivot value:在 pivot 元素前或者后插入 value 这个 元素。
9.存储 sets 类型
在 Redis 中,我们可以将 Set 类型看作为没有排序的字符集合,和 List 类型一样,我们也可
以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。需要说明的是,这些操
作的时间是常量时间。Set 可包含的最大元素数是 4294967295。和 List 类型不同的是,Set 集
合中不允许出现重复的元素。和 List 类型相比,Set 类型在功能上还存在着一个非常重要的特性,
即在服务器端完成多个 Sets 之间的聚合计算操作,如 unions、intersections 和 differences。
由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络 IO 开销
1)sadd key value1、value2…:向 set 中添加数据,如果该 key 的值已有则不会重复添加
2)smembers key:获取 set 中所有的成员
3)scard key:获取 set 中成员的数量
4)sismember key member:判断参数中指定的成员是否在该 set 中,1 表示存在,0 表示
不存在或者该 key 本身就不存在
5)srem key member1、member2…:删除 set 中指定的成员
6)srandmember key:随机返回 set 中的一个成员
7)sdiff key1 key2:返回 key1 与 key2 中相差的成员,而且与 key 的顺序有 关。
即返回差集。
8)sdiffstore destination key1 key2:将 key1、key2 相差的成员存储在
destination 上
9)sinter key[key1,key2…]:返回交集。
10)sinterstore destination key1 key2:将返回的交集存储在 destination 上
11)sunion key1、key2:返回并集。
12)sunionstore destination key1 key2:将返回的并集存储在 destination 上