1.1 NOSQL-Redis
缓存在电商项目乃至互联网项目使用之广,使用的点也非常之多,基本你想到的地方就都有缓存。
1.1.1 为什么要用缓存?
电商网站的行为非常特殊,大量的商品的浏览,对热门的商品,卖的好的商品,评价好的商品浏览频繁。而这部分数据遵循二八定律。只占整体的二成。既然大部分的业务访问都集中在这一小部分数据上,那么如果把这一小部分数据缓存在内存中,是不是就可以减少数据库的访问压力,从而提高整个网站的数据访问速度,改善数据库的写入性能了呢?答案是显而易见的。我们都知道数据库访问创建链接,执行查询,销毁链接是一个非常耗费资源和缓慢的过程。而大量的拦截请求直接从内存读取数据返回给用户。性能提高数百倍。
缓存是改善性能的第一手段。
1.1.2 什么是nosql?
Nosql=no only sql 泛指非关系型数据库。
随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
1.2 主流的NOSQL比较
如下图所示:
1.2.1 主流的NOSQL比较
1.2.2 Redis简介
官网:http://redis.io
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
可以充当缓存、队列等作用。
源码脱管: https://github.com/antirez/redis
1.2.3 历史和发展
2008年,意大利的一家创业公司Merzia推出一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人SalvatoreSanfilippo便对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者PieterNoordhuis一起继续着Redis的开发,直到今天。
短短几年,Redis就拥有了庞大的用户群体。HackerNews在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如京东、淘宝、新浪微博、街旁网、知乎网、国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。
VMware公司从2010年开始赞助Redis的开发,SalvatoreSanfilippo和PieterNoordhuis也分别在3月5月加入VMware,全职开发Redis。
1.2.4 Redis的特性
1)多种数据类型存储
字符串类型
散列类型
列表类型
集合类型
有序集合类型
2)内存存储与持久化
内存的读写速度远快于硬盘
自身提供了持久化功能(RDB、AOF两种方式)
3)功能丰富
可以用作缓存、队列、消息订阅/发布
支持键的生存时间
按照一定规则删除相应的键
4)简单稳定
相比SQL而言更加简洁
不同语言的客户端丰富
基于C语言开发,代码量只有3万多行
1.2.5 版本说明
Redis的版本规则如下:
次版本号(第一个小数点后的数字)为偶数的版本是稳定版本(2.4、2.6等),奇数为非稳定版本(2.5、2.7),一般推荐在生产环境使用稳定版本。
说明:Redis官方是不支持windows平台的,windows版本是由微软自己建立的分支,基于官方的Redis源码上进行编译、发布、维护的,所以windows平台的Redis版本要略低于官方版本。
所以使用redis推荐在linux下使用。从这也可以知道电商项目、互联网项目都是在linux上运行的。
Linux版本3.0.7:
http://download.redis.io/releases/redis-3.0.7.tar.gz
1.2.6 Linux下安装Redis
注意:redis3.0之后引入了集群
mkdir –p /usr/local/src/redis
cd /usr/local/src/redis
wgethttp://download.redis.io/releases/redis-3.0.7.tar.gz
tar xzf redis-3.0.7.tar.gz #tar xvfredis-3.0.7.tar.gz
cd redis-3.0.7
make #下载后编译,过程稍长
make install #进行安装
1.2.7 Windows(64位)安装
Windows(64位)版本2.8.19,需要经过visualstudio编译。
https://github.com/MSOpenTech/redis
Windows(32位)版本已经不再支持。
How to build Redis using Visual Studio
You can use the free Visual Studio Communityedition available athttp://www.visualstudio.com/products/visual-studio-community-vs.
Open the solution file msvs\redisserver.sln inVisual Studio, select a build configuration (Debug or Release) and target(Win32 or x64) then build.
This should create the following executables in themsvs\$(Target)\$(Configuration) folder:
redis-server.exe
redis-benchmark.exe
redis-cli.exe
redis-check-dump.exe
redis-check-aof.exe
1.2.7.1 安装系统服务启动
注册服务:
redis-server --service-install redis.windows.conf--loglevel verbose
卸载服务:
redis-server --service-uninstall
启动Redis:
redis-server --service-start
停止Redis:
redis-server --service-stop
1.3 Redis启动
1.3.1 启动错误
The Windows version of Redis allocates a largememory mapped file for sharing
the heap with the forked process used inpersistence operations. This file
will be created in the current working directory orthe directory specified by
the 'heapdir' directive in the .conf file. Windowsis reporting that there is
insufficient disk space available for this file(Windows error 0x70).
You may fix this problem by either reducing thesize of the Redis heap with
the --maxheap flag, or by moving the heap file to alocal drive with sufficient
space.
Please see the documentation included with thebinary distributions for more
details on the --maxheap and --heapdir flags.
Redis can not continue. Exiting.
redis.conf配置文件中设置
maxheap 1014000000
1.3.2 启动配置
配置文件:redis.conf
设置模式
vi redis.conf
daemonize yes #默认为no
端口配置:
默认6379
配置数据库数量:
Redis默认开启16个数据库,不能像mysql自定义数据库名称,只能是数值,不能修改。
配置内存大小:
会生成一个和内存大小一样的文件。
maxmemory 200mb #在真实环境必须部署,否则物理内存会被耗尽。一般配置200mb/500mb/1gb/2gb。可以分散到多台服务器,和其它业务共享服务器,以充分利用资源。同时因为分散,防止单点故障,造成大量缓存失效。
maxmemory 200mb
1.3.3 启动
redis-server #默认找redis.conf配置文件
redis-server redis6380.conf #指定配置文件,这样可以启动多个实例
1.4 Redis命令
1.4.1 redis-cli的使用之发送命令
默认连接:IP127.0.0.1 端口 6379
redis-cli
指定IP端口:
redis-cli –h127.0.0.1 –p 6379
使用ping命令测试与客户端和服务器链接是否正常
redis-cliping
或
redis-cli
redis127.0.0.1:6379>ping
PONG
1.4.2 redis-cli的使用之命令返回值
状态回复(最简单的回复-redis提供的测试命令)
redis>PING
PONG
127.0.0.1:6379>SET test 123
OK
错误回复(以error开头,后面跟着错误信息)
127.0.0.1:6379>TEST
(error) ERR unknown command 'TEST'
整数回复
127.0.0.1:6379>INCR test_incr
(integer) 1
字符串回复(最长久的一种回复,双引号包裹)
127.0.0.1:6379>get test
“123”
多行字符串回复
127.0.0.1:6379>KEYS *
1) "test_incr"
2) "test"
1.4.3 redis数据库切换SELECT
redis默认支持16个数据库,对外都是以一个从0开始的递增数字命名,可以通过参数database来修改默认数据库个数。客户端连接redis服务后会自动选择0号数据库,可以通过select命令更换数据库,例如选择1号数据库:
127.0.0.1:6379>SELECT 1
OK
127.0.0.1:6379>GET test
(nil)
说明:
Redis不支持自定义数据库名称。
Redis不支持为每个数据库设置访问密码。
Redis的多个数据库之间不是安全隔离的,FLUSHALL命令会清空所有数据库的数据。
1.4.4 redis的基本命令之KEYS
获取符合规则的建名列表。
KEYS *
keys test[_]*
keys t[a-d]
说明:
? 匹配一个字符
* 匹配任意个(包括0个)字符
[] 匹配括号间的任一字符,可以使用“-“表示范围。如a[a-d]匹配ab/ac/ad
\x 匹配字符x,用于转义符合,如果要匹配“?“就需要使用\?
1.4.5 redis的基本命令之EXISTS
判断一个键是否存在。
如果键存在则返回整数类型1,否则返回0。
127.0.0.1:6379> keys *
1) "test_incr"
2) "test"
127.0.0.1:6379> exists test
(integer) 1
127.0.0.1:6379> exists test1
(integer) 0
127.0.0.1:6379>
1.4.6 redis的基本命令之DEL
删除键,可以删除一个或者多个键,多个键用空格隔开,返回值是删除的键的个数。
127.0.0.1:6379> del test
(integer) 1
127.0.0.1:6379> del test
(integer) 0
127.0.0.1:6379> del test test_incr
(integer) 1
127.0.0.1:6379>
1.4.7 redis的基本命令之TYPE
获得键值的数据类型,返回值可能是string(字符串)、hash(散列类型)、list(列表类型)、set(集合类型)、zset(有序集合类型)。
127.0.0.1:6379> keys *
1) "test1"
2) "test"
127.0.0.1:6379> type test
string
127.0.0.1:6379> type test1
string
1.4.8 redis的基本命令之HELP
127.0.0.1:6379> help
redis-cli 2.8.19
Type: "help @<group>" to get a listof commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
127.0.0.1:6379> help type
TYPE key
summary:Determine the type stored at key
since:1.0.0
group:generic
官网:http://www.redis.io帮助
1.4.9 redis的基本命令之FLUSHALL
清空所有数据库。
127.0.0.1:6379> FLUSHALL
OK
1.4.10 redis的基本命令之FLUSHDB
清空当前数据库。
127.0.0.1:6379> FLUSHDB
OK
1.5 Redis数据类型之字符串
存放的字符串为二进制是安全的。字符串长度支持到512M。
1.5.1 基本命令KEYS GET SET
字符串类型是redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据。可以存储JSON化的对象、字节数组等。一个字符串类型键允许存储的数据最大容量是512MB。
赋值与取值:
SET key value
GET key
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> set test1 ab
OK
127.0.0.1:6379> keys *
1) "test1"
2) "test"
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> get test1
"abc"
127.0.0.1:6379> get test2
(nil)
127.0.0.1:6379>
1.5.2 自增INCR/INCRBY
递增数字INCR key
当存储的字符串是整数时,redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。
127.0.0.1:6379> keys *
1) "test1"
2) "test"
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> get test1
"abc"
127.0.0.1:6379> get test2
(nil)
127.0.0.1:6379> incr num
(integer) 1
127.0.0.1:6379> keys *
1) "num"
2) "test1"
3) "test"
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> incr num
(integer) 3
127.0.0.1:6379>
从上面例子可以看出,如果num不存在,则自动会创建,如果存在自动+1。
指定增长系数
语法:INCRBY keyincrement
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> incr num
(integer) 3
127.0.0.1:6379> incrby num 2
(integer) 5
127.0.0.1:6379> incrby num 2
(integer) 7
127.0.0.1:6379> incrby num 2
(integer) 9
127.0.0.1:6379> incr num
(integer) 10
127.0.0.1:6379>
1.5.3 自减DECR/DECRBY
减少指定的整数
DECR key
DECRBY key decrement
127.0.0.1:6379> incr num
(integer) 10
127.0.0.1:6379> decr num
(integer) 9
127.0.0.1:6379> decrby num 3
1.5.4 自加浮点INCRBYFLOAT
整数时,第一次加可以得到正确结果,浮点数后再加浮点就会出现精度问题。
原来下面的例子2.8.7注意在新版本中已经修正了这个浮点精度问题。3.0.7
INCRBYFLOAT key decrement
127.0.0.1:6379> set num
(integer) 131
127.0.0.1:6379> incrfloat num 0.7
“131.7”
127.0.0.1:6379> incrfloat num 0.7
“132.3999999999999999”
1.5.5 尾部追加APPEND
向尾部追加值。如果键不存在则创建该键,其值为写的value,即相当于SET keyvalue。返回值是追加后字符串的总长度。
语法:APPEND keyvalue
127.0.0.1:6379> keys *
1) "num"
2) "test1"
3) "test"
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> append test "abc"
(integer) 6
127.0.0.1:6379> get test
"123abc"
127.0.0.1:6379>
1.5.6 获取字符串长度STRLEN
字符串长度,返回数据的长度,如果键不存在则返回0。注意,如果键值为空串,返回也是0。
语法:STRLEN key
127.0.0.1:6379> get test
"123abc"
127.0.0.1:6379> strlen test
(integer) 6
127.0.0.1:6379> strlen tnt
(integer) 0
127.0.0.1:6379> set tnt ""
OK
127.0.0.1:6379> strlen tnt
(integer) 0
127.0.0.1:6379> exists tnt
(integer) 1
127.0.0.1:6379>
1.5.7 多个MSET MGET
同时设置/获取多个键值
语法:MSET keyvalue [key value …]
MGET key [key …]
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> mset a 1 b 2 c 3
OK
127.0.0.1:6379> mget a b c
1) "1"
2) "2"
3) "3"
127.0.0.1:6379>
1.6 Redis生存时间
1.6.1 Redis之生存时间EXPIRE
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即到期后数据销毁。
语法:EXPIRE keyseconds
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set bomb tnt
OK
127.0.0.1:6379> expire bomb 10
(integer) 1
127.0.0.1:6379> ttl bomb
(integer) 5
127.0.0.1:6379> ttl bomb
(integer) 3
127.0.0.1:6379> ttl bomb
(integer) 3
127.0.0.1:6379> ttl bomb
(integer) 2
127.0.0.1:6379> ttl bomb
(integer) 1
127.0.0.1:6379> ttl bomb
(integer) -2
127.0.0.1:6379> ttl bomb
(integer) -2
127.0.0.1:6379>
TTL查看key的剩余时间,当返回值为-2时,表示键被删除。
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以毫秒为单位,返回 key 的剩余生存时间。
注意:在 Redis 2.8以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。
1.6.2 清除生存时间PERSIST
语法:PERSIST key
127.0.0.1:6379> set bomb tnt
OK
127.0.0.1:6379> expire bomb 60
(integer) 1
127.0.0.1:6379> ttl bomb
(integer) 49
127.0.0.1:6379> persist bomb
(integer) 1
127.0.0.1:6379> ttl bomb
(integer) -1
127.0.0.1:6379>
设置新的数据时需要重新设置该key的生存时间。重新设置值也会清除生存时间。
1.6.3 设置生存时间单位为毫秒PEXPIRE
语法:PEXPIRE keymilliseconds
127.0.0.1:6379> set bomb tnt
OK
127.0.0.1:6379> pexpire bomb 10000
(integer) 1
127.0.0.1:6379> ttl bomb
(integer) 6
127.0.0.1:6379> ttl bomb
(integer) 3
127.0.0.1:6379> ttl bomb
(integer) -2
127.0.0.1:6379>
设置生存时间为毫秒,可以做到更精确的控制。
1.7 安装两个服务
1.7.1 打开6379端口
/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
/etc/rc.d/init.d/iptables save #修改生效
/etc/init.d/iptables status #查看配置
1.7.2 复制改端口无需再次安装
只需要复制配置文件,启动时选择配置文件即可。
#cd /usr/local/src/redis/redis.2.8.17
#cp redis.conf redis6380.conf
#vi redis6380.conf #修改端口为6380
#redis-server redis6380.conf
注意:启动后,会残留些数据,不完全,必须flushall清除掉。