redisnode
1. 性能测试工具(批量写入) ./bin/redis-benchmark -n 10000 一次性写入10000条数据
2.使用select 1能够切换到1号数据库(共有16个数据库)。
【Redis对于key的操做命令】
keys */?/[]:查询相应的key;完整匹配:keys site;模糊匹配:keys s*、keys sit[ey]
randomkey:随机返回key
type key:判断key的类型 string,set,zset,link,hash
exists key:判断key是否存在,返回1/0
del key1 key2 ... KeyN :删除1个或多个键
rename key newkey:给key赋一个新的key名,原值被覆盖
renamenx key newkey:同rename,不覆盖
move key 2:移动key到2号数据库
ttl/pttl key:查询key的剩余生命周期(秒/毫秒)
expire/pexpire key: 设置key的生命周期(秒/毫秒)
persist key: 设置key永久有效
【Redis字符串类型的操做】
set key value [ex]/[px]:多少[秒]/[毫秒]有效。
set key value [nx]/[xx]:设置一个[已存在]/[不存在]的key。
mset:一次性设置多个键值,mset key1 v1 key2 v2 ...。
get key: 获取key的值。
mget key1 key2 ... keyN: 获取多个key的值。
setrange key offset value:从offset个字符开始替换成value。
append key value:把value追加到key的原值上。
getrange key start stop :获取[start, stop]范围。
getset key newvalue :返回旧值并设置新值。
incr/decr key:值加/减1。
incrby/decrby key number:值加/减number。
incrbyfloat key floatnumber:值加浮点值(没有decrbyfloat)
【link 链表结构】
lpush/rpush key value: 把值插入到连接头部/尾部;
lpop/rpop key value: 从连接头部/尾部删除值;
lrange key start stop: 返回[start ,stop]的值,所有:0到-1.
lrem key count value: 从key中删除count个value值
ltrim key start stop: 剪切[start,stop]一段赋给key
lindex key index: 返回index索引上的值。
llen key:计算连接表的元素个数。
linsert key after/before s v: 寻找's'并在其值以前/以后插入v;
rpoplpush source bak: 把source的尾部剪切放在bak的头部;
brpop/blpop key timeout:等待弹出key的尾/头元素
【set无序集合(集合的性质: 惟一性,无序性,肯定性)】
sadd key value1 value2: 往集合key中增长元素.
scard key : 返回元素个数。
smembers key: 返回全部元素。
srandmember key: 返回随机的1个元素。
sismember key v: 判断v是否存在key中,1/0。
srem key v1 v2:删除值为v1和v2的元素,返回真正删除掉的个数。
spop key:返回并删除集合key中1个随机元素。
smove key1 key2 value:把key1中的value值移动到key2中。
sinter k1 k2 k3: 求三者的交集而后返回。
sinterstore dest1 k1 k2 k3: 求交集而后赋给dest1。
sunion k1 k2 k3: 求并集而后返回。
sunionstore dest2 k1 k2 k3: 求并集而后赋给dest2。
sdiff k1 k2 k3: 求差集而后返回。
sdiffstore dest3 k1 k2 k3: 求差集而后赋给dest3。
【order set 有序集合】
zadd key score1 value1 score2 value2 .. :给有序集合添加元素。
zcard key: 返回元素个数。
zcount key min max:分数在[min,max]区间内元素的数量。
zrange/zrevrange key start stop [WITHSCORES] :集合升序/降序排列后返回名次[start,stop]的元素。所有:[0,-1]。
zrangebyscore/zrevrangebyscore key min max [withscores] [limit offset N]: 分数min和max按照分数升续/降序排序。
zrank/zrevrank key member:升序/降序后查询member的排名。
zrem key value1 value2... : 删除集合中的元素。
zremrangebyscore key min max :删除socre在[min,max]之间的。
zremrangebyrank key start end: 删除排名在[start,end]之间的。
zinterstore/zunionstore destination numkeys key1 [key2 ...]:取交集/并集。
【Hash 哈希数据类型】
hset key field value:把key中filed域的值设为value。
hget key field:返回key中field域的值。
hgetall key :返回key中全部域与其值。
hmset key field1 value1 [field2 value2...]:设置多个域和值。
hmget key field1 field2: 返回多个域的值。
hlen key:返回key中元素的数量。
hkeys key:返回key中全部的field。
hvals key:返回key中全部的value。
hexists key field:判断key中有没有field域。
hincrby/hincrbyfloat key field value:把key中的field域的值增加整型值/浮点值value。
hdel key field:删除key中field域。
【Redis的事务】
Mysql:开启[start transaction],语句[普通sql],失败[rollback回滚], 成功[commit].
Redis: 开启[muitl],语句[普通命令],失败[discard取消],成功[exec].
watch key1 key2 keyN:监听key1,key2,keyN有没有变化,若是有变则事务取消。
unwatch:取消全部watch监听。
【消息订阅】
订阅端: Subscribe 频道名称。发布端: publish 频道名称 发布内容。psubscribe 通配符匹配接收。
【运维经常使用的server端命令(不区分大小写)】
time 查看时间戳与微秒数,
dbsize 查看当前库中的key数量,
BgRewriteAof 后台进程重写AOF,
BgSave 后台保存rdb快照,
save 保存rdb快照,
LastSave 上次保存时间,
SlaveOf 设为slave服务器,
shutdown[""|save|nosave] 断开链接,关闭服务器,
SlowLog 显示慢查询,
config get 获取配置信息,
config set 设置配置信息,
monitor 打开控制台,
sync 主从同步,
client list 客户端列表,
client kill 关闭某个客户端,
client setname 为客户端设置名字,
client getname 获取客户端名字,
FlushAll 清空全部db,
FlushDB 清空当前db。
备注:不当心flushall,当即shutdown nosave,编辑aof文件,去掉flushall,而后导入。
【info:显示服务器所有信息】
Memory 内存
Persistence 持久化的信息
Status中的fork耗时
Replication 主从复制的信息
【开发中Redis的key的设计技巧】
MySQL的user表:id:9|name:lisi|pwd:123;
Redis存储:set user:id:9:name lisi|set user:id:9:pwd 123;
查询有哪些字段:keys user:id:9*;
查询某个字段的值:get user:id:9:name;
要按照name查id:set user:name:lisi:id 9;
【Redis实战】
MySQL的user表:
转换为Redis存储:
set user:userid:9:username lisi
set user:userid:9:password 111111
查询方法
(1)查询有哪些字段:keys user:userid:9* ,结果以下:
(2)查询某个字段的值:get user:userid:9:username ===> lisi
注意:冗余字段
按照username查询,须要生成一条按照username列为主的key-value:set user:username:lisi:uid 9
这样就能够根据username:lisi:uid ,查出userid=9。 再查user:9:password/email ...
【增删改查分页完整操做】
使用hash类型存储数据。hmset:批量添加数据,例如:
$redis->hmset(‘user:1’,array(‘name’=>“renxing”,‘age’=>“28”));
hgetall:获取全部数据;
del:删除数据。
$redis->incr("userid"); //设定一个自增的数值,相似于主键
$redis->hmset("user:".$uid,array $add_data); //批量添加
$incr_id = $redis->get("uid"); //获取当前自增的数值
for($i=1;$i<=$incr_id;$i++){
$data[] = $redis->hgetall("user:".$i); //使用hgetall获取数据
}
$res = $redis->del("user:".$uid); //删除数据
[分页操做思路分析] 将全部的uid存在链表结构list中,用rpush uid 1 存储,用lrange uid 0 -1 获取所有数据。在删除数据的时候,用lrem删除对应的id号。PHP中用lsize能够获取list的总数。假设每页显示3条,那么,第1页:lrange uid 0 2,第2页:lrange uid 3 5,第3页:lrange uid 6 8。
【PHP操做Redis】
$redis = new Redis();
$flag = $redis->connect('localhost',6379);
$redis->auth("renxing");//受权
$redis->set('user:id:2:name','lisi');
$value = $redis->get('user:id:2:name');
print_r($value);
【使用hash类型存储数据】
hmset:批量添加数据:$redis->hmset('user:1',array('name'=>'renxing','age'=>'28'));
hgetall:获取全部数据;
del:删除数据。
【执行添加/修改操做 hmset】
$uid = $redis->incr("id");//设定自增
$add_data = array(
"uid"=>$uid,
"username"=>'lisi',
"password"=>'123',
);
$res = $redis->hmset("user:".$uid,$add_data);
此时终端hgetall user:1,获得:uid 1 username lisi password 123。
【获取数据 hgetall】
$incr_id = $redis->get("uid");
for($i=1;$i<=$incr_id;$i++){
$data[] = $redis->hgetall("user:".$i);
}
print_r($data);
【删除操做】
$res = $redis->del("user:".$uid);
【分页】
用lsize获取list的总数,假设每页显示3条,
那么第1页:lrange uid 0 2,第2页:lrange uid 3 5,第3页:lrange uid 6 8。
$count = $redis->lsize("uid"); //用户总数
$page_size = 3;
$page_num = $_GET['page'];
$page_count = ceil($count/$page_size);
$page_up = ($page_num-1)<=1?1:($page_num-1);
$page_down = ($page_num+1)>=$page_count?$page_count:($page_num+1);
$a = ($page_num-1)*$page_size;
$b = $a+$page_size-1;
$ids = $redis->lrange("uid",$a,$b);
foreach($ids as $v){
$data[] = $redis->hgetall("user:".$v);
}
【登陆操做】
存储username和uid的对应关系 $redis->set("username:".$username,$uid);
登陆的时候,使用get 判断username是否存在 $id = $redis->get("username:".$username);
经过$id获得存储在数据库中的password,和用户输入的密码进行判断 $pwd = $redis->hget("user:".$id,"password”);
若是正确了,设置SESSION或者cookie。
Redis与Memcached的区别与比较
1 、Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache只支持简单的数据类型,String。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,能够将内存中的数据保持在磁盘中,重启的时候能够再次加载进行使用,而Memecache把数据所有存在内存之中。
四、
Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的IO复用模型。
使用Redis缓存查询数据
与Memcache的区别:性能相差不大
Redis在2.0版本后增长了本身的VM特性,突破物理内存的限制,Memcache能够修改最大可用内存,
采用LRU算法。
Redis 依赖客户端来实现分布式读写,Memcache自己没有数据冗余机制。
Redis支持(快照、AOF),依赖快照进行持久化,aof加强了可靠性的同时,也对性能有所影响。
Memcache 不支持持久化,一般作缓存,提高性能。
Memcache在并发场景下,用cas保证一致性,redis事务支持比较弱,只能保证事务中的每一个操做连续执行。
Redis支持多种类的数据类型,Redis 用于数据量较小的高性能操做和运算上;
Memcache用于在动态系统中减小数据库负载,提高性能;适合作缓存,提升性能。
1. 使用redis有哪些好处?
(1) 速度快,由于数据存在内存中,相似于HashMap,HashMap的优点就是查找和操做的时间复杂度都是O(1)
(2) 支持丰富数据类型,支持string,list,set,sorted set,hash
(3) 支持事务,操做都是原子性,所谓的原子性就是对数据的更改要么所有执行,要么所有不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过时时间,过时后将会自动删除
3. redis常见性能问题和解决方案:
(1) Master最好不要作任何持久化工做,如RDB内存快照和AOF日志文件
(2) 若是数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和链接的稳定性,Master和Slave最好在同一个局域网内
(4) 尽可能避免在压力很大的主库上增长从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...
这样的结构方便解决单点故障问题,实现Slave对Master的替换。若是Master挂了,能够马上启用Slave1作Master,其余不变。
【redis的rdb和aof】
redis.conf关于rdb的配置:
save 900 1 (900秒以后至少1个关键字发生变化),
save 300 10 (300秒以后至少10个关键字发生变化),
rdb的缺陷:在2个保存点之间断电,将会丢失1-N分钟的数据。
出于对持久化的更精细要求,redis增添了
aof方式 append only file。
把最终的结果逆化为新的变量,只存储最终的结果,忽略中间变化的过程,叫作:
aof重写。
bgrewriteaof 能够直接立刻重写;使用aof后性能稍微会降低。
若是不当心运行了flushall, 当即 shutdown nosave ,关闭服务器。
而后手工编辑aof文件, 去掉文件中的 “flushall ”相关行, 而后开启服务器,就能够导入回原来数据。
若是flushall以后,系统刚好bgrewriteaof了,那么aof就清空了,数据丢失.
aof (append only file)的配置:
appendonly yes (打开aof日志功能),
appendfsync always (每1个命令都当即同步到aof.安全,速度慢,丢失数据少),
appendfsync everysec (折中方案,每秒写1次),
appendfsync no (由操做系统判断缓冲区大小,统一写入到aof.同步频率低,速度快。)
aof重写:只存储最终的结果,忽略中间变化的过程。
auto-aof-rewrite-percentage 100 (.aof文件增加到多少MB时重写),
auto-aof-rewrite-min-size 64mb (当至少大于64MB时再重写),
bgrewriteaof 立刻重写。
rdb和aof能够同时使用,优先使用aof恢复。rdb恢复的快,aof是逐条执行的命令。
rdb和aof的一些注意事项:
(1)在dump rdb过程当中,aof若是中止同步,会不会丢失? (不会,全部的操做缓存在内存的队列里, rdb执行dump完成后,统一操做.)
(2)aof重写是指什么? (aof重写是指把内存中的数据,逆化成命令,写入到.aof日志里.解决 aof日志过大的问题.)
(3)rdb和aof,两种是否能够同时用? (能够,并且推荐这么作)
(4)若是rdb文件和aof文件都存在,优先用谁来恢复数据? (优先aof)
(5)恢复时rdb和aof哪一个恢复的快 (rdb快,由于其是数据的内存映射,直接载入到内存,而aof是命令,须要逐条执行)
【Redis集群】
集群的做用:主从备份,防止主机宕机;读写分离,分担master的任务;任务分离,主从服务器分别负责备份工做与计算工做。
redis集群的实现:
1.官方cluster方案:
从redis 3.0版本开始支持redis-cluster集群,redis-cluster采用无中心结构,每一个节点保存数据和整个集群状态,每一个节点都和其余节点链接。官方推荐的方案是将node配置成主从结构,即一个master主节点,挂n个slave从节点。若是主节点失效,redis cluster会根据选举算法从slave节点中选择一个上升为master节点,整个集群继续对外提供服务。
2.twemproxy代理方案:
Redis代理中间件twemproxy是一种利用中间件作分片的技术。客户端不直接访问redis服务器,而是经过twemproxy代理中间件间接访问。下降了客户端直连后端服务器的链接数量。twemproxy是一个单点,很容易对其形成很大的压力,因此一般会结合keepalived来实现twemproy的高可用。
3.哨兵模式
Sentinel:
是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统能够监视任意多个主服务器以及这些主服务器下的全部从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
4.codis:
codis是一个分布式的Redis解决方案,对于上层的应用来讲,链接codis proxy和链接原生的redis server没什么明显的区别,上层应用能够像使用单机的redis同样使用,codis底层会处理请求的转发,不停机的数据迁移等工做,全部后边的事情,对于前面的客户端来讲是透明的,能够简单的认为后边链接的是一个内存无限大的redis服务。
5.客户端分片:
分区的逻辑在客户端实现,由客户端本身选择请求到哪一个节点。方案可参考一致性哈希,这种方案一般适用于用户对客户端的行为有彻底控制能力的场景。
【总结】
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提高为master,继续提供服务。
Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
缓存雪崩和穿透问题:
缓存穿透:通常的缓存系统,都是按照key去缓存查询,若是不存在对应的value,就应该去后端系统查找(好比DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统形成很大的压力。这就叫作缓存穿透。
如何避免?
1:对查询结果为空的状况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了以后清理缓存。
2:对必定不存在的key进行过滤。能够把全部的可能存在的key放到一个大的Bitmap中,查询时经过该bitmap过滤。
缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。致使系统崩溃。
如何避免?
1:在缓存失效后,经过加锁或者队列来控制读数据库写缓存的线程数量。好比对某个key只容许一个线程查询数据和写缓存,其余线程等待。
2:作二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,能够访问A2,A1缓存失效时间设置为短时间,A2设置为长期
3:不一样的key,设置不一样的过时时间,让缓存失效的时间点尽可能均匀。
Redis里面的 sub 和 pub?
Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能。
基于事件的系统中,Pub/Sub是目前普遍使用的通讯模型,它采用事件做为基本的通讯机制,提供大规模系统所要求的松散耦合的交互模式:
订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;
发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。
Redis的pub/sub是一种消息通讯模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,
Redis做为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。
使用Memcache 缓存查询数据
memcache的工做原理:
Memcache是一个高性能的发布式的内存对象缓存系统,经过在内存里维护一个统一的巨大的hash表,它可以用来存储各类格式的数据,包括图片、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存,而后从内存中读取,从而大大提升读取速度。
memcache的工做流程:
先检查客户端的请求数据是否在memcached中,若有,直接把请求数据返回,再也不对数据库进行任何操做;若是请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中。
memcache的一些方法:
获取:get(key)
设置:set(key, val, expire)
删除:delete(key)
【telnet localhost 11211】
stats 查看状态(stats sizes 表示:64M中使用了 3M)
version 查看版本
添加操做:add myvar1 1 3000 10 //myvar1 键值,1 标志位,3000 存储时间(秒),10 存储的字符数(输入刚才设置的字符数10,举例:helloworld,显示STORED操做成功)。
获取操做:get myvar1 (此时再设置一个myvar1 就会出错)
覆盖操做:set myvar1 1 3000 10
删除操做:delete myvar1
清除全部操做:flush_all
说明:若是重启服务数据就会丢失。
【启动memcached】
memcached -d -m 128 -u root -l localhost -p 11211
/usr/local/memcached/bin/memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid
# 查看内存分配状况:
/usr/local/memcached/bin/memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid -vv
【PHP中测试 Memcache功能】
$mem=new memcache;
$mem->connect("localhost", 11211) or die ("链接失败");
$key = ‘goods_1’;
$data=$mem->get($key);
if(!$data){
$mem->set($key, ‘abcdefg’, MEMCACHE_COMPRESSED, 3600);
}