Redis应用场景说明与部署
Redis简介
REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统。redis和大名鼎鼎的memcached缓存服务很像,但是redis支持的数据存储类型更丰富,但是redis支持的数据存储类型更丰富,包括string(字符串)、list(链表),set(集合)和zset(有序集合)等。
这些数据类型都支持push/pop、add/remove及取交集、并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memchaed缓存服务一样,为了保证效率,数据都是缓存在内存中提供服务。而memcached不同的是,redis持久化存服务还会周期性的把更新的数据写入到磁盘以及把修改的操作记录追加到文件里记录下来,比memcached更有优势的是,redis还支持master-slave(主从)同步,这点很类似关系数据库MySQL。
redis的出现,再一定程序上弥补了memcached这类key-value内存缓存服务的不足,在部分场合可以对关系数据库起到很好的补充作用。redis提供了python,ruby,erlang,php客户端,很方便。
redis官主网站:http://www.redis.io/documentation
http://www.redis.cn/
Redis的优点
与memcache不同:可以持久化存储数据
性能很高:Redis能支持超过100K+每秒的读写频率。
丰富的数据类型:Redis支持二进制的Strings,Lists,Hashes,Sets及Ordered Sets等数据类型操作。
原子:Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰台的特性:Redis还支持publish/subscribe,通知,key过期等等特性。
redis:支持异机主从复制。
Redis的数据类型
Redis最为常用的数据类型主要有以下五种:
String
Hash
List
Set
Sorted set
Redis的应用场景
传统的MySQL+Memcached的网站架构遇到的问题
MySQL数据库实际上是适合进行海量数据存储的,加上通过Memcached将热点数据存放到内存cache里,达到加速数据访问的目的,绝大部分公司都曾经使用过这样的架构,但随着业务的数据量的不断增加和访问量的持续增长,很多问题就会暴露出来:
1、需要不断的对MySQL进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量的开发运维时间。
2、Memcached与MySQL数据库数据一致性问题是个老大难。
3、Memcached数据命中率低或down机,会导致大量访问直接穿透到数据库,导致MySQL无法支撑访问。
4、跨机房cache同步一致性问题。
Redis的最佳应用场景:
1、Redis最佳试用场景是全部数据in-memory。
2、Redis更多场景是作为Memcached的替代品来使用。
3、当需要除key/value之外的更多数据类型支持时,使用Redis更合适。
4、支持持久化。
5、需要负载均衡的场景(redis主从同步)
Redis作者谈Redis应用场景:http://blog.nosqlfan.com/html/2235.html
业务场景:
使用Redis bitmap进行活跃用户统计
http://blog.nosqlfan.com/html/3501.html
Redis小节:
1、提高了DB的可扩展性,只需要将新加的数据放到新加的服务器上就可以了
2、提高了DB的可用性,只影响到需要访问的shard服务器上的数据的用户
3、提供了DB的可维护性,对系统的升级和配置可以按shard一个个来做,对服务产影响小。
一、Redis部署环境搭建
Master:任意IP Centos 6.5
Slave:任意IP Centos 6.5
二、开始安装Redis服务
在Redis的官方网站(www.redis.io)下载最新的稳定版本redis。
操作命令:
- [root@Qinglin-A tools]# wget http://download.redis.io/releases/
- [root@Qinglin-A tools]# tar -xf redis-3.2.2.tar.gz
- [root@Qinglin-A redis-3.2.2]# less README.md
- [root@Qinglin-A redis-3.2.2]# make MALLOC=jemalloc
- [root@Qinglin-A redis-3.2.2]# make PREFIX=/app/redis-3.2.2 install
- [root@Qinglin-A redis-3.2.2]# ln -s /app/redis-3.2.2/ /app/redis
Redis目录结构
- [root@Qinglin-A redis-3.2.2]# tree /app/redis
- /app/redis
- └── bin
- ├── redis-benchmark
- ├── redis-check-aof
- ├── redis-check-rdb
- ├── redis-cli
- ├── redis-sentinel -> redis-server
- └── redis-server
- 1 directory, 6 files
它们的作用如下:
redis-server:redis服务器的daemon启动程序
redis-cli:Redis命令操作工具。当然,也可以telnet根据其纯文本协助来操作。
redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能。
redis-check-aof:更新日志检查
redis-check-dump:用于本地数据库检查
三、配置环境变量,并启动服务
- [root@Qinglin-A redis-3.2.2]# echo 'export PATH=/app/redis/bin:$PATH' >>/etc/profile
- [root@Qinglin-A redis-3.2.2]# tail -1 /etc/profile
- export PATH=/app/redis/bin:$PATH
- [root@Qinglin-A redis-3.2.2]# source /etc/profile
- [root@Qinglin-A redis-3.2.2]# which redis-server
- /app/redis/bin/redis-server
创建Redis配置文件,并重启服务
- [root@Qinglin-A redis-3.2.2]# pwd
- /home/tools/redis-3.2.2
- [root@Qinglin-A redis-3.2.2]# mkdir /app/redis/conf -p
- [root@Qinglin-A redis-3.2.2]# cp redis.conf /app/redis/conf/
- [root@Qinglin-A redis-3.2.2]# redis-server /app/redis/conf/redis.conf & ==>redis启服务
如果错误执行下面的内容
- [root@Qinglin-A redis-3.2.2]# redis-cli shutdown ==>redis重启方式
- 提示错误"vm.overcommit_memory=1"
- [root@Qinglin-A redis-3.2.2]# sysctl vm.overcommit_memory=1
- 提示错误"WARNING you have Transparent Huge Pages (THP) support enabled"
- [root@Qinglin-A redis-3.2.2]# echo 511 > /proc/sys/net/core/somaxconn
- [1]+ Done redis-server /app/redis/conf/redis.conf
- 提示错误"WARNING: The TCP backlog setting of 511"
- [root@Qinglin-A redis-3.2.2]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
下列是帮忙文件,可以指定配置文件启动服务
- [root@Qinglin-A redis-3.2.2]# redis-server --help
- Usage: ./redis-server [/path/to/redis.conf] [options]
- ./redis-server - (read config from stdin)
- ./redis-server -v or --version
- ./redis-server -h or --help
- ./redis-server --test-memory
- Examples:
- ./redis-server (run the server with default conf)
- ./redis-server /etc/redis/6379.conf
- ./redis-server --port 7777
- ./redis-server --port 7777 --slaveof 127.0.0.1 8888
- ./redis-server /etc/myredis.conf --loglevel verbose
- Sentinel mode:
- ./redis-server /etc/sentinel.conf --sentinel
检查服务端口
- [root@Qinglin-A redis-3.2.2]# lsof -i:6379
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- redis-ser 5847 root 4u IPv4 23427 0t0 TCP localhost:6379 (LISTEN)
四、测试Redis
使用redis-cli客户端
cli帮忙文档
- [root@Qinglin-A redis-3.2.2]# redis-cli --help
- redis-cli 3.2.2
- Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
- -h Server hostname (default: 127.0.0.1).
- -p Server port (default: 6379).
- -s Server socket (overrides hostname and port).
- -a Password to use when connecting to the server.
- -r Execute specified command N times.
- -i When -r is used, waits seconds per command.
- It is possible to specify sub-second times like -i 0.1.
- -n Database number.
- -x Read last argument from STDIN.
- -d Multi-bulk delimiter in for raw formatting (default: \n).
- -c Enable cluster mode (follow -ASK and -MOVED redirections).
- --raw Use raw formatting for replies (default when STDOUT is
- not a tty).
- --no-raw Force formatted output even when STDOUT is not a tty.
- --csv Output in CSV format.
- --stat Print rolling stats about server: mem, clients, ...
- --latency Enter a special mode continuously sampling latency.
- --latency-history Like --latency but tracking latency changes over time.
- Default time interval is 15 sec. Change it using -i.
- --latency-dist Shows latency as a spectrum, requires xterm 256 colors.
- Default time interval is 1 sec. Change it using -i.
- --lru-test Simulate a cache workload with an 80-20 distribution.
- --slave Simulate a slave showing commands received from the master.
- --rdb Transfer an RDB dump from remote server to local file.
- --pipe Transfer raw Redis protocol from stdin to server.
- --pipe-timeout In --pipe mode, abort with error if after sending all data.
- no reply is received within seconds.
- Default timeout: 30. Use 0 to wait forever.
- --bigkeys Sample Redis keys looking for big keys.
- --scan List all keys using the SCAN command.
- --pattern Useful with --scan to specify a SCAN pattern.
- --intrinsic-latency Run a test to measure intrinsic system latency.
- The test will run for the specified amount of seconds.
- --eval Send an EVAL command using the Lua script at .
- --ldb Used with --eval enable the Redis Lua debugger.
- --ldb-sync-mode Like --ldb but uses the synchronous Lua debugger, in
- this mode the server is blocked and script changes are
- are not rolled back from the server memory.
- --help Output this help and exit.
- --version Output version and exit.
- Examples:
- cat /etc/passwd | redis-cli -x set mypasswd
- redis-cli get mypasswd
- redis-cli -r 100 lpush mylist x
- redis-cli -r 100 -i 1 info | grep used_memory_human:
- redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
- redis-cli --scan --pattern '*:12345*'
- (Note: when using --eval the comma separates KEYS[] from ARGV[] items)
- When no command is given, redis-cli starts in interactive mode.
- Type "help" in interactive mode for information on available commands
- and settings.
redis登录
redis -h主机
- [root@Qinglin-A redis-3.2.2]# redis-cli
- 127.0.0.1:6379>
- 127.0.0.1:6379>
set创建key
set 001工号 qinglin名子
- 127.0.0.1:6379> set no001 qinglin
- OK
get获取key
- 127.0.0.1:6379> get no001
- "qinglin"
通过远程获取key
- [root@Qinglin-A redis-3.2.2]# redis-cli -h 127.0.0.1 -p 6379 get no001
- "qinglin"
删除key,并查看
- 127.0.0.1:6379> del set no001
- (integer) 1
- 127.0.0.1:6379> get no001
- (nil)
telnet测试方法
- [root@Qinglin-A ~]# telnet 127.0.0.1 6379
- Trying 127.0.0.1...
- Connected to 127.0.0.1.
- Escape character is '^]'.
- set no002 test
- +OK
- get no002
- $4
- test
五、Redis多数据类型介绍
1、字符串类型
这是最简单的redis类型,如果你只用这种类型,redis就是一个可以持久化的memcached服务器。
(注:memcache 的数据仅仅保存在内在中,服务器重启后,数据将丢失)。
- 127.0.0.1:6379> set mykey "my name is guanqinglin"
- OK
- 127.0.0.1:6379> get mykey
- "my name is guanqinglin"
“my name is guanqinglin” 正如你所见到的,通常用SET和GET来设置和获取字符串值。
值可以是任何各种类的字符串(包括二进制数据)例如你可以在一个键下保存一副jpeg图片。值的长度不能超过1GB。
虽然字符串是Redis的基本值类型,但是你仍然能通过它完成一些有趣的操作。
例如:原子递增
- 127.0.0.1:6379> set counter 100
- OK
- 127.0.0.1:6379> incr counter
- (integer) 101
- 127.0.0.1:6379> incr counter
- (integer) 102
- 127.0.0.1:6379> incr counter 10
- 127.0.0.1:6379> incrby counter 10
- (integer) 112
INCR命令将字符串值解析成整型,将其加1,最后将结果保存为新的字符串值,数亿的命令有INCRBY,DECR and DECRBY。实际上他们在内部就是同一个命令,只是看上去有点不同。
2、列表类型
要说清楚列表数据类型,最好先讲一点儿理论背景,在信息技术List这个词常常被使用不当。例如“Python Lists”就名不副实(名为Linked Lists),但他们实际上是数组(同样的数据类型在Ruby中叫数组)。
一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个例表,但用数组实现的List和Linked List实现的list,在属性方面大不相同。
Redis lists基于Linked list实现。这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是常数级别的。用LPUSH命令在十个元素的list头部添加新元素,和在千万元素的list头部添加新元素的速度相同。
那么,坏消息是什么?在数组实现的List中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。
Redis Lists用linked list实现的原因是:对于数据库系统来说,到头重要的特性是:能非常快的在很大的列表上添加元素,另一个重要因素是,正如你将要看到的:Redis lists能在常数时间取得常数长度。
Redis lists入门
LPUSH命令可向list的左边(头部)添加一个新元素,而RPUSH命令可向list的右边(尾部)添加一个新元素,最后LRANGE命令可从list中取一定范围的元素
- 127.0.0.1:6379> RPUSH list1 "Guanqinglin"
- (integer) 1
- 127.0.0.1:6379> RPUSH list1 "Shuaige"
- (integer) 2
- 127.0.0.1:6379> RPUSH list1 "shi"
- (integer) 3
- 127.0.0.1:6379> RPUSH list1 "zhende"
- (integer) 4
- 127.0.0.1:6379> LRANGE list1 0 1
- 1) "Guanqinglin"
- 2) "Shuaige"
- 127.0.0.1:6379> LRANGE list1 0 2
- 1) "Guanqinglin"
- 2) "Shuaige"
- 3) "shi"
- 127.0.0.1:6379> LRANGE list1 0 3
- 1) "Guanqinglin"
- 2) "Shuaige"
- 3) "shi"
- 4) "zhende"
3、Redis集合
Redis集合是未排序的集合,其元素是二进制安全的字符串。SADD命令可以向集合加添一个新元素。和sets相关的操作也有许多,比如检测某个元素是否存在,以及实现交集并集,差集等等。一例胜千言:
- 127.0.0.1:6379> SADD myset guan
- (integer) 1
- 127.0.0.1:6379> SADD myset qing
- (integer) 1
- 127.0.0.1:6379> SADD myset lin
- (integer) 1
- 127.0.0.1:6379> SMEMBERS myset
- 1) "guan"
- 2) "lin"
- 3) "qing"
我向集合中添加了三个元素,并让Redis返回所有元素。如你所见他们是无序的。
现在让我们检查某个元素是否存在:
- 127.0.0.1:6379> SISMEMBER myset guan
- (integer) 1
- 127.0.0.1:6379> SISMEMBER myset shuai
- (integer) 0
guan是这个集合的成员,而shuai不是,集合特别适合表现对像之间的关系,例如用Redis集合可以很容易实现标签功能。
五、PHP安装redis客户端扩展
获取源码包
- [root@Qinglin-A ~]# file master
- master: Zip archive data, at least v1.0 to extract
- [root@Qinglin-A ~]# wget --no-check-certificate https://codeload.github.com/phpredis/phpredis/zip/master
安装(注本机必须已经安装PHP程序)
- [root@Qinglin-A ~]# unzip master
- [root@Qinglin-A ~]# cd phpredis-master/
- [root@Qinglin-A /]# /application/php5.3.27/bin/phpize
- Configuring for:
- PHP Api Version: 20090626
- Zend Module Api No: 20090626
- Zend Extension Api No: 220090626
- [root@Qinglin-A phpredis-master]# ./configure --with-php-config=/application/php5.3.27/bin/php-config
- [root@Qinglin-A phpredis-master]# make
- [root@Qinglin-A phpredis-master]# make install
修改php.ini设置,重启php
- [root@Qinglin-A /]# echo 'extension = redis.so' >>/application/php5.3.27/lib/php.ini
六、redis配置文件介绍及主从同步配置讲解
主配置文件
- /app/redis/conf/redis.conf
从库加上主库的IP即可实现主从同步
- [root@Qinglin-A /]# vim /app/redis/conf/redis.conf
- # slaveof
- slaveof 10.0.0.1 6379
监控命令(如果从库执行该命令会一直ping主库)
- [root@Qinglin-A /]# redis-cli -h localhost -p 6379 monitor
- OK
- ”PING“
redis功能统计
- [root@Qinglin-A /]# redis-cli -h localhost -p 6379 info
- # Server
- redis_version:3.2.2
- redis_git_sha1:00000000
- redis_git_dirty:0
- redis_build_id:cbd0cdda28fdd323
- redis_mode:standalone
- os:Linux 2.6.32-431.el6.x86_64 x86_64
- arch_bits:64
- multiplexing_api:epoll
- gcc_version:4.4.7
- process_id:2457
- run_id:69d1c0246acc88922030a99b8bf9509168123f8d
- tcp_port:6379
- uptime_in_seconds:6192
- uptime_in_days:0
- hz:10
- lru_clock:11052524
- executable:/root/redis-server
- config_file:/app/redis/conf/redis.conf
- # Clients
- connected_clients:1
- client_longest_output_list:0
- client_biggest_input_buf:0
- blocked_clients:0
- # Memory
- used_memory:821984
- used_memory_human:802.72K
- used_memory_rss:2732032
- used_memory_rss_human:2.61M
- used_memory_peak:821984
- used_memory_peak_human:802.72K
- total_system_memory:1036648448
- total_system_memory_human:988.62M
- used_memory_lua:37888
- used_memory_lua_human:37.00K
- maxmemory:0
- maxmemory_human:0B
- maxmemory_policy:noeviction
- mem_fragmentation_ratio:3.32
- mem_allocator:jemalloc-4.0.3
- # Persistence
- loading:0
- rdb_changes_since_last_save:0
- rdb_bgsave_in_progress:0
- rdb_last_save_time:1470666679
- rdb_last_bgsave_status:ok
- rdb_last_bgsave_time_sec:0
- rdb_current_bgsave_time_sec:-1
- aof_enabled:0
- aof_rewrite_in_progress:0
- aof_rewrite_scheduled:0
- aof_last_rewrite_time_sec:-1
- aof_current_rewrite_time_sec:-1
- aof_last_bgrewrite_status:ok
- aof_last_write_status:ok
- # Stats
- total_connections_received:3
- total_commands_processed:42
- instantaneous_ops_per_sec:0
- total_net_input_bytes:1744
- total_net_output_bytes:17746419
- instantaneous_input_kbps:0.00
- instantaneous_output_kbps:0.00
- rejected_connections:0
- sync_full:0
- sync_partial_ok:0
- sync_partial_err:0
- expired_keys:0
- evicted_keys:0
- keyspace_hits:11
- keyspace_misses:1
- pubsub_channels:0
- pubsub_patterns:0
- latest_fork_usec:293
- migrate_cached_sockets:0
- # Replication
- role:master
- connected_slaves:0
- master_repl_offset:0
- repl_backlog_active:0
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:0
- repl_backlog_histlen:0
- # CPU
- used_cpu_sys:9.77
- used_cpu_user:4.39
- used_cpu_sys_children:0.01
- used_cpu_user_children:0.00
- # Cluster
- cluster_enabled:0
- # Keyspace
- db0:keys=3,expires=0,avg_ttl=0
或查看单个CPU的内容
- [root@Qinglin-A /]# redis-cli -h localhost -p 6379 info CPU
- # CPU
- used_cpu_sys:9.83
- used_cpu_user:4.44
- used_cpu_sys_children:0.01
- used_cpu_user_children:0.00