应用程序处理的数据越来越多,对并发访问的要求越来越大,程序的性能却并没有提升。发布日期越近,我们的心情就越想热锅上的蚂蚁,那叫一个急啊!不停的做性能剖析,做性能调优,却百思不得其解。幸好,我们及时遇到了Redis,让性能瞬间提升了百倍,真的有一种山穷水尽疑无路,柳暗花明又一村的感觉!今天我们就简单介绍一下Redis的一些用法,给大家的性能调优提供一种新的思路。
Redis 简介
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API, 包括Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等
Redis 是一个高性能的key-value数据库,它支持存储的value类型包括string (字符串)、list(链表)、set(集合)、zset(sorted set–有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis支持各种不同方式的排序。
为了保证效率,数据都是缓存在内存中,并且周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis在一些应用场合可以对关系数据库起到很好的补充作用。在某些场合,可以认为Redis是一个内存数据库,通过内存缓存功能来达到性能的极大提升。
Redis可以通过两种方式安装
从redis.io下载最新版redis-X.Y.Z.tar.gz后解压,然后进入redis-X.Y.Z文件夹后直接make即可
#sudo apt-get install redis-server
这种方式安装的redis server不是最新版本,但是满足基本使用是没有问题的
Redis提供了丰富的配置,缺省配置文件是安装根目录下的redis.conf。通常情况下大部分配置项只需要保持缺省值就能满足大多数应用场景,下面是一些常用的配置项。
daemonize no
缺省为no
bind 192.168.1.100 10.0.0.1
缺省会响应本机所有可用网卡的连接请求,如果要响应所有机器的连接,需要修改为bind 0.0.0.0
port 6379
loglevel notice
logfile
如果为空,则日志会输出到标准输出
databases 16
这16个数据库的编号将是0到15。默认的数据库是编号为0的数据库。用户可以使用select <DBid>来选择相应的数据库
save 900 1 // 表示每15 分钟且至少有1 个key 改变,就触发一次持久化
save 300 10 // 表示每5 分钟且至少有10 个key 改变,就触发一次持久化
save 60 10000 // 表示每60 秒至少有10000 个key 改变,就触发一次持久化
禁用RDB持久化的策略,只要不设置任何save指令就可以,或者给save传入一个空字符串参数也可以达到相同效果
slaveof <masterip> <masterport>
appendonly no
redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了
#src/redis-cli
src/redis-cli> shutdown
> keys *
> set keyname keyvalue
> get keyname
> exists larry
(integer) 0
> del lv
> expire larry 10
(integer) 1
> move larry ad4
(integer) 1
> persist lv
(integer) 1
> randomkey
> rename
> ping
PONG
> echo name
“larry”
> select ad4databank
OK
> quit
> dbsize
(integer) 12
> info
> config get
> flushdb
> flushall
因为Redis的数据操作非常简单,应用程序API接口用法也非常直观明了,有了相应的第三方库支持,连接上Redis Server之后,剩下的就是很简单的一些操作,上面第四节中命令支持的,应用程序API接口也基本上都支持。
引入Jedis这个第三方库之后,就可以用例子代码进行简单的数据插入和查询动作了
public static void main(String[] args) {
Jedis jedis = new Jedis(“147.151.240.234”,6379);
jedis.set(“foo”, “bar”);
String value = jedis.get(“foo”);
System.out.println(value);
}
当然也有好事者对Jedis进行了进一步封装,使得该API更方便灵活,很有名的例子就是Jfinal中的RedisPlugin
首先需要安装python的支持库,通过执行命令sudo apt-get install python-redis或者在Windows环境下执行pip install redis即可,接下来就是对数据的增删查操作了,非常直观
import redis
r = redis.Redis(host=’10.0.1.7′, port=6379, db=1)
# 查数据库大小
print ‘/ndbsize: %s’ % r.dbsize()
# 塞数据
r[‘c1’] = ‘bar’
#或者
r.set(‘c2′,’bar’)
# 取数据
print ‘r[”]:’,r[‘c1’]
#或者
print ‘get:’,r.get(‘a’)
#或者 同时取一批
print ‘mget:’,r.mget(‘c1′,’c2’)
#或者 同时取一批 它们的名字(key)很像 而恰好你又不想输全部
print ‘keys:’,r.keys(‘c*’)
#又或者 你只想随机取一个:
print ‘randomkey:’,r.randomkey()
# 查看一个数据有没有 有 1 无0
print ‘existes:’,r.exists(‘a’)
# 删数据 1是删除成功 0和None是没这个东西
print ‘delete:’,r.delete(‘cc’)
# 哦对了 它是支持批量操作的
print ‘delete:’,r.delete(‘c1′,’c2’)
在我们的项目中,Redis作为关系型数据库的一个内存缓存,当有用户查询时,先查看Redis中是否有用户需要的信息,有的话直接返回;没有需要的信息,再到关系型数据库中进行查询,同时查询的结果缓存到Redis中,加快后续查询的性能。总体而言,使用Redis之后,整个应用程序的性能提升了上百倍。