优点:

  • 1、丰富的数据存储类型(string,list,set,zset)
  • 2、丰富的操作方式,都是原子性!
  • 3、支持主从同步
  • 4、与memcached不同可持久化缓存数据
  • 5、redis提供python,ruby,erlang,php客户端,使用方便

性能:

  • 1、redis支持超过100k+每秒的读写频率
  • 2、丰富的数据类型:redis支持二进制的strings,Lists,Hashes,Sets与Ordered Sets
  • 3、原子:Redis的所有操作都是原子性的,同时redis还支持几个操作合并后的原子性
  • 执行
  • 4、丰富的特性:Redis还支持publish/pubscribe,订阅发布功能,通知,key过期等等
    特性
  • 5、redis支持多机主从同步

redis最佳应用场景:

  • 全部数据in-memory
  • 更多场景作为memcached的替代品
  • 当需要除k,v之外更多数据类型支持时,选择redis更加合适
  • down机重启数据还可以继续
  • 需要负载均衡的场景(redis主从同步)

业务场景

  • 1、使用Redis bitmap进行活跃用户统计
  • 2、strom流计算的top结果

install redis

1
2
3
4
5
6
whoami@ubuntu:~$ wget http://download.redis.io/releases/redis-3.0.5.tar.gz
whoami@ubuntu:~$ tar -zxvf redis-3.0.5.tar.gz
whoami@ubuntu:~$ cd redis-3.0.5/

whoami@ubuntu:~/redis-3.0.5$ make
make[1]: Leaving directory `/home/whoami/redis-3.0.5/src'

Starting Redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
whoami@ubuntu:~/redis-3.0.5$ nohup src/redis-server > redis-server.log &

whoami@ubuntu:~/redis-3.0.5$ src/redis-cli
127.0.0.1:6379> set name "whoami"
OK
127.0.0.1:6379> get name
"whoami"

127.0.0.1:6379> help get

GET key
summary: Get the value of a key
since: 1.0.0
group: string

#设置超时时间
127.0.0.1:6379> set name 'rain' Ex 10
OK
127.0.0.1:6379> get name
"rain"
127.0.0.1:6379> get name
"rain"
127.0.0.1:6379> get name
(nil)

python install redis model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
whoami@ubuntu:~/redis-3.0.5$ sudo pip install redis
Downloading/unpacking redis
Downloading redis-2.10.5-py2.py3-none-any.whl (60kB): 60kB downloaded
Installing collected packages: redis
Successfully installed redis
Cleaning up...

>>> import redis
>>> conn = redis.Redis('localhost')
>>> conn.set('name','whoami')
True
>>> conn.get('name')
'whoami'

#!/usr/bin/env python
# coding: utf-8
__author__ = 'whoami'

#redis_test.py
"""
@version: 1.0
@author: whoami
@license: Apache Licence 2.0
@contact: [email protected]
@site: http://www.itweet.cn
@software: PyCharm Community Edition
@file: redis_test.py
@time: 2015-11-25 下午10:51
"""

import redis

conn = redis.Redis(host='localhost',port=6379,db=0,password=None)

conn.set('name','whoami')

print conn.get('name')

Pub/Sub

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
http://redis.io/topics/pubsub

RedisHelper.py
#!/usr/bin/env python
# coding: utf-8
__author__ = 'whoami'

"""
@version: 1.0
@author: whoami
@license: Apache Licence 2.0
@contact: [email protected]
@site: http://www.itweet.cn
@software: PyCharm Community Edition
@file: RedisHelper.py
@time: 2015-11-25 下午11:11
"""
import redis

class RedisHelper:

def __init__(self):
self.__conn = redis.Redis(host='127.0.0.1')
self.chan_sub = 'fm87.7'
self.chan_pub = 'fm87.7'

def get(self,key):
return self.__conn.get(key)

def set(self,key,value):
return self.__conn.set(key,value)

def public(self,msg):
self.__conn.publish(self.chan_pub,msg)
return True

def subscribe(self):
pub = self.__conn.pubsub()
pub.subscribe(self.chan_sub)
pub.parse_response()
return pub

if __name__ == '__main__':
t = RedisHelper()
t.public('test')

#测试订阅发布功能
whoami@ubuntu:~/py/demo/day8$ python RedisHelper.py

#此时收不到消息,因为是实时的,只有开启此频道,在发送才能接受到消息
whoami@ubuntu:~/py/demo/day8$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tab,RedisHelper
>>> r = RedisHelper.RedisHelper()
>>> recv = r.subscribe()
>>> recv.parse_response() #这一步的时候在发送就会不断收到客户端发送过来的消息
>>> recv.parse_response() #阻塞模式,没有数据就阻塞,有数据就返回
['message', 'fm87.7', 'test']
>>> recv.parse_response()
['message', 'fm87.7', 'test1']
>>> recv.parse_response()
['message', 'fm87.7', 'test2']

>>> recv.get_message() #非阻塞,如果没有消息立即返回,有消息立即处理
{'pattern': None, 'type': 'message', 'channel': 'fm87.7', 'data': 'whoami'}

===========================================================================
++++++++++++++++https://pypi.python.org/pypi/redis/2.10.5++++++++++++++++++
Publish / Subscribe
redis-py includes a PubSub object that subscribes to channels and listens for new messages. Creating a PubSub object is easy.

>>> r = redis.StrictRedis(...)
>>> p = r.pubsub()
Once a PubSub instance is created, channels and patterns can be subscribed to.

>>> p.subscribe('my-first-channel', 'my-second-channel', ...)
>>> p.psubscribe('my-*', ...)
The PubSub instance is now subscribed to those channels/patterns. The subscription confirmations can be seen by reading messages from the PubSub instance.

>>> p.get_message()
{'pattern': None, 'type': 'subscribe', 'channel': 'my-second-channel', 'data': 1L}
>>> p.get_message()
{'pattern': None, 'type': 'subscribe', 'channel': 'my-first-channel', 'data': 2L}
>>> p.get_message()
{'pattern': None, 'type': 'psubscribe', 'channel': 'my-*', 'data': 3L}
Every message read from a PubSub instance will be a dictionary with the following keys.

type: One of the following: ‘subscribe’, ‘unsubscribe’, ‘psubscribe’, ‘punsubscribe’, ‘message’, ‘pmessage’
channel: The channel [un]subscribed to or the channel a message was published to
pattern: The pattern that matched a published message’s channel. Will be None in all cases except for ‘pmessage’ types.
data: The message data. With [un]subscribe messages, this value will be the number of channels and patterns the connection is currently subscribed to. With [p]message messages, this value will be the actual published message.
===========================================================================

list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
127.0.0.1:6379> LPUSH list 'whoami' 'root'
(integer) 2
127.0.0.1:6379> LRANGE list 0 2
1) "root"
2) "whoami"
127.0.0.1:6379> LRANGE list 1 2
1) "whoami"

127.0.0.1:6379> RPUSH list 'rain' 'boot'
127.0.0.1:6379> LRANGE list 0 4
1) "root"
2) "whoami"
3) "rain"
4) "boot"

# 持久化数据到磁盘
127.0.0.1:6379> save
127.0.0.1:6379> help save

SAVE -
summary: Synchronously save the dataset to disk
since: 1.0.0
group: server

Command Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
$ less README

$ src/redis-benchmark
====== PING_INLINE ======
100000 requests completed in 0.97 seconds
50 parallel clients
3 bytes payload
keep alive: 1

99.49% <= 1 milliseconds
100.00% <= 1 milliseconds
102669.41 requests per second
====== MSET (10 keys) ======
100000 requests completed in 1.78 seconds
50 parallel clients
3 bytes payload
keep alive: 1

85.98% <= 1 milliseconds
98.14% <= 2 milliseconds
99.32% <= 3 milliseconds
99.95% <= 4 milliseconds
99.95% <= 11 milliseconds
99.95% <= 15 milliseconds
100.00% <= 15 milliseconds
56053.81 requests per second

$ src/redis-
redis-benchmark
redis-check-aof
redis-check-dump
redis-cli
redis-sentinel
redis-server
redis-trib.rb

# help redis server
$ redis-server --help

# starting redis
$ export PATH=/home/whoami/redis-3.0.5/src

$ which redis-server
~/redis-3.0.5/src/redis-server

$ redis-server
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.

WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

$ sudo sysctl vm.overcommit_memory=1
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# echo 511 > /proc/sys/net/core/somaxconn

$ lsof -i :6379
redis-ser 4487 whoami 4u IPv6 20311 0t0 TCP *:6379 (LISTEN)

-- $ killall redis-server
$ src/redis-cli shutdown
$ lsof -i :6379
[1]+ Done src/redis-server

# redis cli
[whoami@apache-server redis-3.0.5]$ redis-cli
127.0.0.1:6379> KEYS *
1) "key:__rand_int__"
2) "mylist"
3) "counter:__rand_int__"

# starting redis && Test redis
# 交互方式一
$ src/redis-cli --help
$ src/redis-cli -h localhost -p 6379
localhost:6379> help @string
localhost:6379> help get

GET key
summary: Get the value of a key
since: 1.0.0
group: string

localhost:6379> set whoami beijing
OK
localhost:6379> get whoami
"beijing"

#交互方式二
$ src/redis-cli -h localhost -p 6379 set whoami shanghai
OK
$ src/redis-cli -h localhost -p 6379 get whoami
"shanghai"

$ src/redis-cli -h localhost -p 6379 del whoami
(integer) 1
$ src/redis-cli -h localhost -p 6379 get whoami
(nil)

$ telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set whoami beijing
+OK
get whoami
$7
beijing
^]
telnet> quit
Connection closed.

# 多数据类型
1、字符串,值可以是任何种类的字符串(包括二进制),列如可以在一个键下面保存一副图片,值得长度不能超过1G!
$ src/redis-cli set mykey 'my binary safe value'
OK
$ src/redis-cli get mykey
"my binary safe value"

1.1、counter incr自增命令
[whoami@apache-server redis-3.0.5]$ src/redis-cli set counter 100
OK
[whoami@apache-server redis-3.0.5]$ src/redis-cli incr counter
(integer) 101
[whoami@apache-server redis-3.0.5]$ src/redis-cli incr counter
(integer) 102
[whoami@apache-server redis-3.0.5]$ src/redis-cli incr counter
(integer) 103

2、列表类型
[whoami@apache-server redis-3.0.5]$ src/redis-cli rpush message 'Hello how are you?'
(integer) 1
[whoami@apache-server redis-3.0.5]$ src/redis-cli rpush message 'Hello how are you?'
(integer) 1
[whoami@apache-server redis-3.0.5]$ src/redis-cli rpush message 'who am i ?'
(integer) 2
[whoami@apache-server redis-3.0.5]$ src/redis-cli rpush message 'this is the...'
(integer) 3
[whoami@apache-server redis-3.0.5]$ src/redis-cli lrange message 0 2
1) "Hello how are you?"
2) "who am i ?"
3) "this is the..."

[whoami@apache-server redis-3.0.5]$ src/redis-cli lrange message 0 1
1) "Hello how are you?"
2) "who am i ?"

3、集合
[whoami@apache-server redis-3.0.5]$ src/redis-cli sadd myset a
(integer) 1
[whoami@apache-server redis-3.0.5]$ src/redis-cli sadd myset b
(integer) 1
[whoami@apache-server redis-3.0.5]$ src/redis-cli sadd myset c
(integer) 1
[whoami@apache-server redis-3.0.5]$ src/redis-cli smembers myset
1) "b"
2) "a"
3) "c"

4、常见5种数据类型
- string 字符串
- hash 哈希
- list 列表数据
- set 集合
- sorted set 排序集合

redis配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ cat redis.conf |grep 16
# bind 192.168.1.100 10.0.0.1
databases 16

#保存数据到disk
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save ""

save 900 1
save 300 10
save 60 10000

主从同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
---启动主库
$ src/redis-server ../redis-3.0.5/redis.conf &

---slave配置
yum install gcc
[whoami@server1 ~]$ wget http://download.redis.io/releases/redis-3.0.5.tar.gz
[whoami@server1 ~]$ tar -zxvf redis-3.0.5.tar.gz
[whoami@server1 ~]$ cd redis-3.0.5
[whoami@server1 redis-3.0.5]$ make PREFIX=/home/whoami/redis install
cd src && make install

[whoami@server1 redis-3.0.5]$ mkdir /home/whoami/redis/conf

[whoami@server1 redis-3.0.5]$ cd /home/whoami/redis/conf/

[whoami@server1 conf]$ cat redis.conf |grep slaveof
# Master-Slave replication. Use slaveof to make a Redis instance a copy of
# slaveof <masterip> <masterport>
slaveof 192.168.2.125 6379
# masterauth <master-password>

#关闭防火墙
[whoami@server1 conf]$ /etc/init.d/network stop

#启动从库
[whoami@server1 redis]$ ../redis/bin/redis-server /home/whoami/redis/conf/redis.conf &
-----------------------------------------------------------------------------
从库信息
5306:S 02 Jan 18:37:05.235 * Connecting to MASTER 192.168.2.125:6379
5306:S 02 Jan 18:37:05.235 * MASTER <-> SLAVE sync started
5306:S 02 Jan 18:37:05.238 * Non blocking connect for SYNC fired the event.
5306:S 02 Jan 18:37:05.238 * Master replied to PING, replication can continue...
5306:S 02 Jan 18:37:05.238 * Partial resynchronization not possible (no cached master)
5306:S 02 Jan 18:37:05.266 * Full resync from master: 56fcc0b35ec0a8b0bcfb4c8929d2b82ebe6c0c55:1
5306:S 02 Jan 18:37:05.396 * MASTER <-> SLAVE sync: receiving 400209 bytes from master
5306:S 02 Jan 18:37:05.408 * MASTER <-> SLAVE sync: Flushing old data
5306:S 02 Jan 18:37:05.409 * MASTER <-> SLAVE sync: Loading DB in memory
5306:S 02 Jan 18:37:05.448 * MASTER <-> SLAVE sync: Finished with success
-----------------------------------------------------------------------------
主库信息
1469:M 02 Jan 17:54:52.913 * DB loaded from disk: 0.029 seconds
1469:M 02 Jan 17:54:52.913 * The server is now ready to accept connections on port 6379
1469:M 02 Jan 18:20:49.134 * Slave 192.168.2.200:6379 asks for synchronization
1469:M 02 Jan 18:20:49.134 * Full resync requested by slave 192.168.2.200:6379
1469:M 02 Jan 18:20:49.134 * Starting BGSAVE for SYNC with target: disk
1469:M 02 Jan 18:20:49.148 * Background saving started by pid 1503
1503:C 02 Jan 18:20:49.198 * DB saved on disk
1503:C 02 Jan 18:20:49.198 * RDB: 10 MB of memory used by copy-on-write
1469:M 02 Jan 18:20:49.291 * Background saving terminated with success
1469:M 02 Jan 18:20:49.303 * Synchronization with slave 192.168.2.200:6379 succeeded
-----------------------------------------------------------------------------

# 从库启动监控
[whoami@server1 redis]$ /home/whoami/redis/bin/redis-cli -h localhost -p 6379 monitor
OK
1451731377.726230 [0 192.168.2.125:6379] "PING"

#测试主从同步
---主库操作
[whoami@apache-server redis-3.0.5]$ src/redis-cli -h localhost -p 6379 set whoami 123
OK
[whoami@apache-server redis-3.0.5]$ src/redis-cli -h localhost -p 6379 get whoami
"123"
[whoami@apache-server redis-3.0.5]$ src/redis-cli -h localhost -p 6379 set whoami abc
OK
[whoami@apache-server redis-3.0.5]$ src/redis-cli -h localhost -p 6379 get whoami
"abc"

---从库验证
[whoami@apache-server redis-3.0.5]$ src/redis-cli -h 192.168.2.200 -p 6379 get whoami
"123"

---查看从库监控
[whoami@server1 redis]$ /home/whoami/redis/bin/redis-cli -h localhost -p 6379 monitor
OK
1451731377.726230 [0 192.168.2.125:6379] "PING"
1451731387.824175 [0 192.168.2.125:6379] "PING"
1451731397.922070 [0 192.168.2.125:6379] "PING"
1451731407.875624 [0 192.168.2.125:6379] "SELECT" "0"
1451731407.875640 [0 192.168.2.125:6379] "set" "whoami" "abc"
1451731408.009269 [0 192.168.2.125:6379] "PING"

[whoami@apache-server ~]$ killall redis-server

redis 监控信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[whoami@server1 ~]$ /home/whoami/redis/bin/redis-cli -h localhost -p 6379 info|wc -l
100

[whoami@server1 ~]$ /home/whoami/redis/bin/redis-cli -h localhost -p 6379 info Replication
# Replication
role:slave
master_host:192.168.2.125
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:1039
slave_priority:100
slave_read_only:1
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

[whoami@server1 ~]$ /home/whoami/redis/bin/redis-cli -h localhost -p 6379 info CPU
# CPU
used_cpu_sys:0.36
used_cpu_user:0.15
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

redis负载均衡

1
2
lvs-->master
|--slave

redis cluster

1
后续更新...