redis完全解读

redis是什么:

Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.

redis是开源,BSD许可,高级的key-value存储系统

可以用来存储字符串,哈希结构,链表,集合,因此,常用来提供数据结构服务.

redismemcached相比,的独特之处:

1: redis可以用来做存储(storge), memccached是用来做缓存(cache)

  这个特点主要因为其有”持久化”的功能.

2: 存储的数据有”结构”,对于memcached来说,存储的数据,只有1种类型--”字符串”,

  而redis则可以存储字符串,链表,哈希结构,集合,有序集合.

Redis下载安装

1:官方站点: redis.io 下载最新版或者最新stable

2:解压源码并进入目录

3: 不用configure

4: 直接make 

(如果是32位机器 make 32bit)

:易碰到的问题,时间错误.

原因源码是官方configure过的,但官方configure,生成的文件有时间戳信息,

Make只能发生在configure之后,

如果你的虚拟机的时间不对,比如说是2012

解决: date -s ‘yyyy-mm-dd hh:mm:ss’   重写时间

    再 clock -w  写入cmos

5: 可选步骤: make test  测试编译情况

(可能出现: need tcl  >8.4这种情况, yum install tcl)

6: 安装到指定的目录,比如 /usr/local/redis

make  PREFIX=/usr/local/redis install

: PREFIX要大写

7: make install之后,得到如下几个文件

redis-benchmark  性能测试工具

redis-check-aof  日志文件检测工(比如断电造成日志损坏,可以检测并修复)

redis-check-dump  快照文件检测工具,效果类上

redis-cli  客户端

redis-server 服务端

8: 复制配置文件

Cp /path/redis.conf /usr/local/redis

9: 启动与连接

/path/to/redis/bin/redis-server  ./path/to/conf-file

例:[root@localhost redis]# ./bin/redis-server ./redis.conf 

连接redis-cli

#/path/to/redis/bin/redis-cli [-h localhost -p 6379 ]

10: redis以后台进程的形式运行

编辑conf配置文件,修改如下内容;

daemonize yes


Redis对于key的操作命令

del key1 key2 ... Keyn

作用删除1个或多个键

返回值不存在的key忽略掉,返回真正删除的key的数量

rename key newkey

作用key赋一个新的key

:如果newkey已存在,newkey的原值被覆盖

renamenx key newkey  

作用key改名为newkey

返回发生修改返回1,未发生修改返回0

: nx--> not exists, , newkey不存在时,作改名动作

move key db

redis 127.0.0.1:6379[1]> select 2

OK

redis 127.0.0.1:6379[2]> keys *

(empty list or set)

redis 127.0.0.1:6379[2]> select 0

OK

redis 127.0.0.1:6379> keys *

1) "name"

2) "cc"

3) "a"

4) "b"

redis 127.0.0.1:6379> move cc 2

(integer) 1

redis 127.0.0.1:6379> select 2

OK

redis 127.0.0.1:6379[2]> keys *

1) "cc"

redis 127.0.0.1:6379[2]> get cc

"3"

(注意一个redis进程,打开了不止一个数据库默认打开16个数据库,015编号,

如果想打开更多数据库,可以从配置文件修改)


keys pattern 查询相应的key

redis,允许模糊查询key

3个通配符 *, ? ,[]

*: 通配任意多个字符

?: 通配单个字符

[]: 通配括号内的某1个字符

redis 127.0.0.1:6379> flushdb

OK

redis 127.0.0.1:6379> keys *

(empty list or set)

redis 127.0.0.1:6379> mset one 1 two 2 three 3 four 4

OK

redis 127.0.0.1:6379> keys o*

1) "one"

redis 127.0.0.1:6379> key *o

(error) ERR unknown command 'key'

redis 127.0.0.1:6379> keys *o

1) "two"

redis 127.0.0.1:6379> keys ???

1) "one"

2) "two"

redis 127.0.0.1:6379> keys on?

1) "one"

redis 127.0.0.1:6379> set ons yes

OK

redis 127.0.0.1:6379> keys on[eaw]

1) "one"

randomkey 返回随机key

exists key

判断key是否存在,返回1/0

type key

返回key存储的值的类型

string,link,set,order set, hash

ttl key 

作用查询key的生命周期

返回秒数

:对于不存在的key或已过期的key/不过期的key,都返回-1

Redis2.8,对于不存在的key,返回-2

expire key 整型值

作用设置key的生命周期,以秒为单位

同理

pexpire key 毫秒数设置生命周期

pttl  key, 以毫秒返回生命周期

persist key

作用把指定key置为永久有效


Redis字符串类型的操作

set key value [ex 秒数] / [px 毫秒数]  [nx] /[xx]

: set a 1 ex 10 , 10秒有效

Set a 1 px 9000  , 9秒有效

如果ex,px同时写,以后面的有效期为准

如 set a 1 ex 100 px 9000, 实际有效期是9000毫秒

nx: 表示key不存在时,执行操作

xx: 表示key存在时,执行操作

mset  multi set , 一次性设置多个键值

: mset key1 v1 key2 v2 ....

get key 

作用:获取key的值

mget key1 key2 ..keyn

作用:获取多个key的值

setrange key offset value

作用:把字符串的offset偏移字节,改成value

redis 127.0.0.1:6379> set greet hello

OK

redis 127.0.0.1:6379> setrange greet 2 x

(integer) 5

redis 127.0.0.1:6379> get greet

"hexlo"

注意如果偏移量>字符长度该字符自动补0x00

redis 127.0.0.1:6379> setrange greet 6 !

(integer) 7

redis 127.0.0.1:6379> get greet

"heyyo\x00!"

append key value

作用value追加到key的原值上

getrange key start stop

作用是获取字符串中 [start, stop]范围的值

注意对于字符串的下标,左数从0开始,右数从-1开始

redis 127.0.0.1:6379> set title 'chinese'

OK

redis 127.0.0.1:6379> getrange title 0 3

"chin"

redis 127.0.0.1:6379> getrange title 1 -2

"hines"

注意

1: start>=length, 则返回空字符串

2: stop>=length,则截取至字符结尾

3: 如果start 所处位置在stop右边返回空字符串

getset key newvalue

作用获取并返回旧值,设置新值

redis 127.0.0.1:6379> set cnt 0

OK

redis 127.0.0.1:6379> getset cnt 1

"0"

redis 127.0.0.1:6379> getset cnt 2

"1"

incr key

作用指定的key的值加1,并返回加1后的值

注意:

1:不存在的key当成0,incr操作

2: 范围为64有符号

incrby key number

redis 127.0.0.1:6379> incrby age  90

(integer) 92

incrbyfloat key floatnumber

redis 127.0.0.1:6379> incrbyfloat age 3.5

"95.5"

decr key

redis 127.0.0.1:6379> set age 20

OK

redis 127.0.0.1:6379> decr age

(integer) 19

decrby key number

redis 127.0.0.1:6379> decrby age 3

(integer) 16

getbit key offset

作用:获取值的二进制表示,对应位上的值(从左,0编号)

redis 127.0.0.1:6379> set char A

OK

redis 127.0.0.1:6379> getbit char 1

(integer) 1

redis 127.0.0.1:6379> getbit char 2

(integer) 0

redis 127.0.0.1:6379> getbit char 7

(integer) 1

setbit  key offset value

设置offset对应二进制位上的值

返回该位上的旧值

注意

1:如果offset过大,则会在中间填充0,

2: offset最大大到多少

3:offset最大2^32-1,可推出最大的的字符串为512M

bitop operation destkey key1 [key2 ...]

key1,key2..keyNoperation,并将结果保存到 destkey 上。

operation 可以是 AND 、 OR 、 NOT 、 XOR

redis 127.0.0.1:6379> setbit lower 7 0

(integer) 0

redis 127.0.0.1:6379> setbit lower 2 1

(integer) 0

redis 127.0.0.1:6379> get lower

" "

redis 127.0.0.1:6379> set char Q

OK

redis 127.0.0.1:6379> get char

"Q"

redis 127.0.0.1:6379> bitop or char char lower

(integer) 1

redis 127.0.0.1:6379> get char

"q"

注意: 对于NOT操作, key不能多个


link 链表结构

lpush key value 

作用把值插入到链接头部

rpop key

作用返回并删除链表尾元素

rpush,lpop: 不解释

lrange key start  stop

作用返回链表中[start ,stop]中的元素

规律左数从0开始,右数从-1开始

lrem key count value

作用key链表中删除 value

删除count的绝对值个value后结束

Count>0 从表头删除

Count<0 从表尾删除

ltrim key start stop

作用剪切key对应的链接,[start,stop]一段,并把该段重新赋给key

lindex key index

作用返回index索引上的值,

如  lindex key 2

llen key

作用:计算链接表的元素个数

redis 127.0.0.1:6379> llen task

(integer) 3

redis 127.0.0.1:6379> 

linsert  key after|before search value

作用key链表中寻找’search’,并在search值之前|之后,.插入value

一旦找到一个search,命令就结束了,因此不会插入多个value

rpoplpush source dest

作用source的尾部拿出,放在dest的头部,

并返回 该单元值

场景: task + bak 双链表完成安全队列

Task列表                             bak列表

业务逻辑:

1:Rpoplpush task bak

2:接收返回值,并做业务处理

3:如果成功,rpop bak 清除任务如不成功,下次从bak表里取任务

brpop ,blpop  key timeout

作用:等待弹出key的尾/头元素

Timeout为等待超时时间

如果timeout0,则一直等待

场景长轮询Ajax,在线聊天时,能够用到


Setbit 的实际应用

场景: 1亿个用户每个用户 登陆/做任意操作  ,记为 今天活跃,否则记为不活跃

每周评出有奖活跃用户连续7天活动

每月评,等等...

思路

Userid   dt  active

1        2013-07-27  1

1       2013-0726   1

如果是放在表中, 1:表急剧增大,2:要用group ,sum运算,计算较慢

位图法 bit-map

Log0721:  ‘011001...............0’

......

log0726 :   ‘011001...............0’

Log0727 :  ‘0110000.............1’

1: 记录用户登陆:

每天按日期生成一个位图用户登陆后,user_id位上的bit值置为1

2: 1周的位图  and 计算

位上为1,即是连续登陆的用户

redis 127.0.0.1:6379> setbit mon 100000000 0

(integer) 0

redis 127.0.0.1:6379> setbit mon 3 1

(integer) 0

redis 127.0.0.1:6379> setbit mon 5 1

(integer) 0

redis 127.0.0.1:6379> setbit mon 7 1

(integer) 0

redis 127.0.0.1:6379> setbit thur 100000000 0

(integer) 0

redis 127.0.0.1:6379> setbit thur 3 1

(integer) 0

redis 127.0.0.1:6379> setbit thur 5 1

(integer) 0

redis 127.0.0.1:6379> setbit thur 8 1

(integer) 0

redis 127.0.0.1:6379> setbit wen 100000000 0

(integer) 0

redis 127.0.0.1:6379> setbit wen 3 1

(integer) 0

redis 127.0.0.1:6379> setbit wen 4 1

(integer) 0

redis 127.0.0.1:6379> setbit wen 6 1

(integer) 0

redis 127.0.0.1:6379> bitop and  res mon feb wen

(integer) 12500001

如上例,优点:

1: 节约空间, 1亿人每天的登陆情况,1亿bit,1200WByte,10M 的字符就能表示

2: 计算方便

 

集合 set 相关命令

集合的性质唯一性,无序性,确定性

stringlink的命令中,可以通过range 来访问string中的某几个字符或某几个元素

,因为集合的无序性,无法通过下标或范围来访问部分元素.

因此想看元素,要么随机先一个,要么全选

sadd key  value1 value2

作用往集合key中增加元素

srem value1 value2

作用删除集合中集为 value1 value2的元素

返回值忽略不存在的元素后,真正删除掉的元素的个数

spop key

作用返回并删除集合中key1个随机元素

随机--体现了无序性

srandmember key

作用返回集合key,随机的1个元素.

sismember key  value

作用判断value是否在key集合中

是返回1,否返回0

smembers key

作用返回集中中所有的元素

scard key

作用返回集合中元素的个数

smove source dest value

作用:source中的value删除,并添加到dest集合中

sinter  key1 key2 key3

作用求出key1 key2 key3 三个集合中的交集,并返回

redis 127.0.0.1:6379> sadd s1 0 2 4 6

(integer) 4

redis 127.0.0.1:6379> sadd s2 1 2 3 4

(integer) 4

redis 127.0.0.1:6379> sadd s3 4 8 9 12

(integer) 4

redis 127.0.0.1:6379> sinter s1 s2 s3

1) "4"

redis 127.0.0.1:6379> sinter s3 s1 s2

1) "4"

sinterstore dest key1 key2 key3

作用求出key1 key2 key3 三个集合中的交集,并赋给dest

suion key1 key2.. Keyn

作用求出key1 key2 keyn的并集,并返回

sdiff key1 key2 key3 

作用求出key1key2 key3的差集

key1-key2-key3 


order set 有序集合

zadd key score1 value1 score2 value2 ..

添加元素

redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lilei 21 lilei

(integer) 3

zrem key value1 value2 ..

作用删除集合中的元素

zremrangebyscore key min max

作用按照socre来删除元素,删除score[min,max]之间的

redis 127.0.0.1:6379> zremrangebyscore stu 4 10

(integer) 2

redis 127.0.0.1:6379> zrange stu 0 -1

1) "f"

zremrangebyrank key start end

作用按排名删除元素,删除名次在[start,end]之间的

redis 127.0.0.1:6379> zremrangebyrank stu 0 1

(integer) 2

redis 127.0.0.1:6379> zrange stu 0 -1

1) "c"

2) "e"

3) "f"

4) "g"

zrank key member

查询member的排名(升续 0名开始)

zrevrank key memeber

查询 member的排名(降续 0名开始)

ZRANGE key start stop [WITHSCORES]

把集合排序后,返回名次[start,stop]的元素

默认是升续排列 

Withscores 是把score也打印出来

zrevrange key start stop

作用:把集合降序排列,取名字[start,stop]之间的元素

zrangebyscore  key min max [withscores] limit offset N

作用集合(升续)排序后,score[min,max]内的元素,

并跳过 offset取出N

redis 127.0.0.1:6379> zadd stu 1 a 3 b 4 c 9 e 12 f 15 g

(integer) 6

redis 127.0.0.1:6379> zrangebyscore stu 3 12 limit 1 2 withscores

1) "c"

2) "4"

3) "e"

4) "9"

zcard key

返回元素个数

zcount key min max

返回[min,max] 区间内元素的数量

zinterstore destination numkeys key1 [key2 ...] 

[WEIGHTS weight [weight ...]] 

[AGGREGATE SUM|MIN|MAX]

key1,key2的交集,key1,key2的权重分别是 weight1,weight2

聚合方法用: sum |min|max

聚合的结果,保存在dest集合内

注意: weights ,aggregate如何理解?

如果有交集交集元素又有socre,score怎么处理?

 Aggregate sum->score相加   , min 求最小score, max 最大score

可以通过weigth设置不同key的权重交集时,socre * weights

详见下例

redis 127.0.0.1:6379> zadd z1 2 a 3 b 4 c

(integer) 3

redis 127.0.0.1:6379> zadd z2 2.5 a 1 b 8 d

(integer) 3

redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2

(integer) 2

redis 127.0.0.1:6379> zrange tmp 0 -1

1) "b"

2) "a"

redis 127.0.0.1:6379> zrange tmp 0 -1 withscores

1) "b"

2) "4"

3) "a"

4) "4.5"

redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2 aggregate sum

(integer) 2

redis 127.0.0.1:6379> zrange tmp 0 -1 withscores

1) "b"

2) "4"

3) "a"

4) "4.5"

redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2 aggregate min

(integer) 2

redis 127.0.0.1:6379> zrange tmp 0 -1 withscores

1) "b"

2) "1"

3) "a"

4) "2"

redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2 weights 1 2

(integer) 2

redis 127.0.0.1:6379> zrange tmp 0 -1 withscores

1) "b"

2) "5"

3) "a"

4) "7"


Hash 哈希数据类型相关命令

hset key field value

作用key中 filed域的值设为value

:如果没有field,直接添加,如果有,则覆盖原field域的值

hmset key field1 value1 [field2 value2 field3 value3 ......fieldn valuen]

作用设置field1->N 个域对应的值是value1->N

(对应PHP理解为  $key = array(file1=>value1, field2=>value2 ....fieldN=>valueN))

hget key field

作用返回keyfield域的值

hmget key field1 field2 fieldN

作用返回keyfield1 field2 fieldN域的值

hgetall key

作用:返回key,所有域与其值

hdel key field

作用删除key中 field

hlen key

作用返回key中元素的数量

hexists key field

作用判断key中有没有field

hinrby key field value

作用是把key中的field域的值增长整型值value

hinrby float  key field value

作用是把key中的field域的值增长浮点值value

hkeys key

作用返回key中所有的field

kvals key

作用返回key中所有的value


Redis 中的事务

Redis支持简单的事务

Redis与 mysql事务的对比

Mysql

Redis

开启

start transaction

muitl

语句

普通sql

普通命令

失败

rollback 回滚

discard 取消

成功

commit

exec

: rollbackdiscard 的区别

如果已经成功执行了2条语句3条语句出错.

Rollback,2条的语句影响消失.

Discard只是结束本次事务,2条语句造成的影响仍然还在

:

mutil后面的语句中语句出错可能有2种情况

1: 语法就有问题

这种,exec,报错所有语句得不到执行

2: 语法本身没错,但适用对象有问题比如 zadd 操作list对象

Exec之后,会执行正确的语句,并跳过有不适当的语句.

(如果zadd操作list这种事怎么避免这一点,由程序员负责)

思考

我正在买票

Ticket -1 , money -100

而票只有1如果在我multi之后,exec之前票被别人买了---ticket变成0.

我该如何观察这种情景,并不再提交

悲观的想法

世界充满危险,肯定有人和我抢给 ticket上锁只有我能操作. [悲观锁]

乐观的想法:

没有那么人和我抢,因此,我只需要注意,

--有没有人更改ticket的值就可以了 [乐观锁]

Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.

具体的命令----  watch命令

redis 127.0.0.1:6379> watch ticket

OK

redis 127.0.0.1:6379> multi

OK

redis 127.0.0.1:6379> decr ticket

QUEUED

redis 127.0.0.1:6379> decrby money 100

QUEUED

redis 127.0.0.1:6379> exec

(nil)   // 返回nil,说明监视的ticket已经改变了,事务就取消了.

redis 127.0.0.1:6379> get ticket

"0"

redis 127.0.0.1:6379> get money

"200"

watch key1 key2  ... keyN

作用:监听key1 key2..keyN有没有变化,如果有变则事务取消

unwatch 

作用取消所有watch监听


消息订阅

使用办法:

订阅端: Subscribe 频道名称

发布端: publish 频道名称 发布内容

客户端例子:

redis 127.0.0.1:6379> subscribe news

Reading messages... (press Ctrl-C to quit)

1) "subscribe"

2) "news"

3) (integer) 1

1) "message"

2) "news"

3) "good good study"

1) "message"

2) "news"

3) "day day up"

服务端例子:

redis 127.0.0.1:6379> publish news 'good good study'

(integer) 1

redis 127.0.0.1:6379> publish news 'day day up'

(integer) 1


Redis持久化配置

Redis的持久化有2种方式   1快照  2是日志

Rdb快照的配置选项

save 900 1      // 900,1条写入,则产生快照 

save 300 1000   // 如果300秒内有1000次写入,则产生快照

save 60 10000  // 如果60秒内有10000次写入,则产生快照

(3个选项都屏蔽,rdb禁用)

stop-writes-on-bgsave-error yes  // 后台备份进程出错时,主进程停不停止写入?

rdbcompression yes    // 导出的rdb文件是否压缩

Rdbchecksum   yes //  导入rbd恢复时数据时,要不要检验rdb的完整性

dbfilename dump.rdb  //导出来的rdb文件名

dir ./  //rdb的放置路径

Aof 的配置

appendonly no # 是否打开 aof日志功能

appendfsync always   # 1个命令,都立即同步到aof. 安全,速度慢

appendfsync everysec # 折衷方案,每秒写1

appendfsync no      # 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof. 同步频率低,速度快,

no-appendfsync-on-rewrite  yes: # 正在导出rdb快照的过程中,要不要停止同步aof

auto-aof-rewrite-percentage 100 #aof文件大小比起上次重写时的大小,增长率100%,重写

auto-aof-rewrite-min-size 64mb #aof文件,至少超过64M,重写


dump rdb过程中,aof如果停止同步,会不会丢失?

不会,所有的操作缓存在内存的队列里, dump完成后,统一操作.

: aof重写是指什么?

: aof重写是指把内存中的数据,逆化成命令,写入到.aof日志里.

以解决 aof日志过大的问题.

如果rdb文件,aof文件都存在,优先用谁来恢复数据?

: aof

: 2种是否可以同时用?

可以,而且推荐这么做

恢复时rdbaof哪个恢复的快

: rdb,因为其是数据的内存映射,直接载入到内存,aof是命令,需要逐条执行
redis 服务器端命令

redis 127.0.0.1:6380> time  ,显示服务器时间 时间戳(), 微秒数

1) "1375270361"

2) "504511"

redis 127.0.0.1:6380> dbsize  // 当前数据库的key的数量

(integer) 2

redis 127.0.0.1:6380> select 2

OK

redis 127.0.0.1:6380[2]> dbsize

(integer) 0

redis 127.0.0.1:6380[2]> 

BGREWRITEAOF 后台进程重写AOF

BGSAVE       后台保存rdb快照

SAVE         保存rdb快照

LASTSAVE     上次保存时间

Slaveof master-Host port  , 把当前实例设为masterslave

Flushall  清空所有库所有键 

Flushdb  清空当前库所有键

Showdown [save/nosave]

如果不小心运行了flushall, 立即 shutdown nosave ,关闭服务器

然后 手工编辑aof文件去掉文件中的 “flushall ”相关行然后开启服务器,就可以导入回原来数据.

如果,flushall之后,系统恰好bgrewriteaof,那么aof就清空了,数据丢失.

Slowlog 显示慢查询

:多慢才叫慢

slowlog-log-slower-than 10000 ,来指定,(单位是微秒)

服务器储存多少条慢查询的记录?

 slowlog-max-len 128 ,来做限制

Info [Replication/CPU/Memory..] 

查看redis服务器的信息

Config get 配置项  

Config set 配置项 值 (特殊的选项,不允许用此命令设置,slave-of, 需要用单独的slaveof命令来设置)


Redis运维时需要注意的参数

1: 内存

# Memory

used_memory:859192 数据结构的空间

used_memory_rss:7634944 实占空间

mem_fragmentation_ratio:8.89 2者的比例,1.N为佳,如果此值过大,说明redis的内存的碎片化严重,可以导出再导入一次.

2: 主从复制

# Replication

role:slave

master_host:192.168.1.128

master_port:6379

master_link_status:up

3:持久化

# Persistence

rdb_changes_since_last_save:0

rdb_last_save_time:1375224063

4: fork耗时

#Status

latest_fork_usec:936  上次导出rdb快照,持久化花费微秒

注意如果某实例有10G内容,导出需要2分钟,

每分钟写入10000,导致不断的rdb导出,磁盘始处于高IO状态.

5: 慢日志

config get/set slowlog-log-slower-than

CONFIG get/SET slowlog-max-len 

slowlog get N 获取慢日志


运行时更改master-slave

修改一台slave(设为A)new master 

1) 命令该服务不做其他redis服务的slave 

   命令: slaveof no one 

2) 修改其readonlyyes

其他的slave再指向new master A

1) 命令该服务为new master Aslave

   命令格式 slaveof IP port
监控工具 sentinel

Sentinel不断与master通信,获取masterslave信息.

监听masterslave的状态

如果某slave失效,直接通知master去除该slave.

如果master失效,,是按照slave优先级(可配置), 选取1slave做 new master

,把其他slave--> new master

疑问: sentinelmaster通信,如果某次因为master IO操作频繁,导致超时,

此时,认为master失效,很武断.

解决: sentnel允许多个实例看守1master, N(N可设置)sentinel都认为master失效,才正式失效.

Sentinel选项配置

port 26379 # 端口

sentinel monitor mymaster 127.0.0.1 6379 2 ,

给主机起的名字(不重即可), 

2sentinel实例都认为master失效时,正式失效

sentinel down-after-milliseconds mymaster 30000  多少毫秒后连接不到master认为断开

sentinel can-failover mymaster yes #是否允许sentinel修改slave->master. 如为no,则只能监控,无权修改./

sentinel parallel-syncs mymaster 1 , 一次性修改几个slave指向新的new master.

sentinel client-reconfig-script mymaster /var/redis/reconfig.sh ,# 在重新配置new master,new slave过程,可以触发的脚本
redis 与关系型数据库的适合场景

书签系统

create table book (

bookid int,

title char(20)

)engine myisam charset utf8;

insert into book values 

(5 , 'PHP圣经'),

(6 , 'ruby实战'),

(7 , 'mysql运维')

(8, 'ruby服务端编程');

create table tags (

tid int,

bookid int,

content char(20)

)engine myisam charset utf8;

insert into tags values 

(10 , 5 , 'PHP'),

(11 , 5 , 'WEB'),

(12 , 6 , 'WEB'),

(13 , 6 , 'ruby'),

(14 , 7 , 'database'),

(15 , 8 , 'ruby'),

(16 , 8 , 'server');

既有web标签,又有PHP,同时还标签的书,要用连接查询

select * from tags inner join tags as t on tags.bookid=t.bookid

where tags.content='PHP' and t.content='WEB';


换成key-value存储

kv 来存储

set book:5:title 'PHP圣经'

set book:6:title 'ruby实战'

set book:7:title 'mysql运难'

set book:8:title ‘ruby server’

sadd tag:PHP 5

sadd tag:WEB 5 6

sadd tag:database 7

sadd tag:ruby 6 8

sadd tag:SERVER 8

查: 既有PHP,又有WEB的书

Sinter tag:PHP tag:WEB  #查集合的交集

PHP或有WEB标签的书

Sunin tag:PHP tag:WEB

:含有ruby,不含WEB标签的书

Sdiff tag:ruby tag:WEB #求差集


Redis key 设计技巧

1: 把表名转换为key前缀 如, tag:

2: 2段放置用于区分区key的字段--对应mysql中的主键的列名,userid

3: 3段放置主键值,2,3,4...., a , b ,c

4: 4,写要存储的列名

用户表 user  , 转换为key-value存储

userid

username

passworde

email

9

Lisi

1111111

[email protected]

set  user:userid:9:username lisi

set  user:userid:9:password 111111

set  user:userid:9:email   [email protected]

keys user:userid:9*

注意:

在关系型数据中,除主键外,还有可能其他列也步骤查询,

如上表中, username 也是极频繁查询的,往往这种列也是加了索引的.

转换到k-v数据中,则也要相应的生成一条按照该列为主的key-value

Set  user:username:lisi:uid  9  

这样,我们可以根据username:lisi:uid ,查出userid=9, 

再查user:9:password/email ...

完成了根据用户名来查询用户信息
php-redis扩展编译

1: pecl.php.net  搜索redis

2: 下载stable(稳定版)扩展

3: 解压,

4: 执行/php/path/bin/phpize (作用是检测PHP的内核版本,并为扩展生成相应的编译配置)

5: configure --with-php-config=/php/path/bin/php-config

6: make && make install

引入编译出的redis.so插件

1: 编辑php.ini

2: 添加

redis插件的使用

// get instance

$redis = new Redis();

// connect to redis server

$redis->open('localhost',6380);

$redis->set('user:userid:9:username','wangwu');

var_dump($redis->get('user:userid:9:username'));


微博项目的key设计

全局相关的key:

表名

global

列名

操作

备注

Global:userid

incr

产生全局的userid

Global:postid

Incr

产生全局的postid

用户相关的key()

表名

user

Userid

Username

Password

Authsecret

3

Test3

1111111

#U*Q(%_

redis,变成以下几个key

Key前缀

user

User:Userid:*

User:userid:*Username

User:userid:*Password

User:userid:*:Authsecret

User:userid:3

User:userid:3:Test3

User:userid:3:1111111

User:userid:3:#U*Q(%_

微博相关的表设计

表名

post

Postid

Userid

Username

Time 

Content

4

2

Lisi

1370987654f

测试内容

微博在redis,与表设计对应的key设计

Key前缀

post

Post:Postid:*

Post:postid:*Userid

Post:postid:*:Username

Post:postid:*:Time 

Post:postid:*:Content

4

2

Lisi

1370987654f

测试内容


关注表: following

Following:$userid -->

粉丝表

Follower:$userid --->

推送表:revicepost

3

4

7

=================拉模型,改进=====================

拉取表

3

4

7

上次我拉取了 A->5,67,三条微博下次刷新home.php, >7的微博开始拉取

解决拉取时,设定一个lastpull时间点下次拉取时,>lastpull的微博

有很多关注人,如何取?

解决循环自己的关注列表,逐个取他们的新微博

取出来之后放在哪儿?

: pull:$userid的链接里

如果个人中心,只有前1000

: ltrim,只取前1000

如果我关注 A,B两人2人中,各取3条最新信息

,3+3条信息从时间上,是交错的如何按时间排序?

我们发布时是发布的hash结构不能按时间来排序.

解决:  同步时,取微博后,记录本次取的微博的最大id,

下次同步时,只取比最大id更大的微博


Time taken for tests:   32.690 seconds

Complete requests:      20000

Failed requests:        0

Write errors:           0

Non-2xx responses:      20000

Total transferred:      13520000 bytes

Total POSTed:           5340000

HTML transferred:       9300000 bytes

Requests per second:    611.80 [#/sec] (mean)

Time per request:       81.726 [ms] (mean)

Time per request:       1.635 [ms] (mean, across all concurrent requests)

Transfer rate:          403.88 [Kbytes/sec] received

                        159.52 kb/s sent

                        563.41 kb/s total

Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        0    0   0.9      0      19

Processing:    14   82   8.4     81     153

Waiting:        4   82   8.4     80     153

Total:         20   82   8.2     81     153

Percentage of the requests served within a certain time (ms)

  50%     81

  66%     84

  75%     86

  80%     88

  90%     93

  95%     96

  98%    100

  99%    103

 100%    153 (longest request)

测试结果:

50个并发, 20000次请求虚拟下,未做特殊优化

每次请求redis写操作6.

30+秒左右完成.

平均每秒发布700条微博, 4000redis写入.

后台定时任务,回归冷数据入mysql
Redis配置文件

 daemonize yes  # redis是否以后台进程运行

 Requirepass  密码 配置redis连接的密码

:配置密码后,客户端连上服务器,需要先执行授权命令

# auth 密码


支持一下呗

redis完全解读_第1张图片

你可能感兴趣的:(redis)