获取列表片段
redis 127.0.0.1:6379> LRANGE KEY_NAME START END
lrange命令比较常用,返回从start到stop的所有元素的列表,start和stop都是从0开始。
(1)查询所有(获取全部列表):LRANGE KEY_NAME 0 -1
1.41.88.9:63789[1]> LRANGE myList2 0 -1 1) "b" 2) "e" 3) "g" 4) "b" 5) "f" 6) "e" 7) "b" 8) "d" 9) "c" 10) "b" 11) "e" 12) "a" 13) "d" 14) "c" 15) "b" 16) "a"
(2)查询前两个:LRANGE KEY_NAME 0 2
12.4.8.2:63789[1]> LRANGE myList2 -2 -1 1) "b" 2) "a"
(3)lrange还支持负值索引,这里是负值大家可以把负号加值直接理解成从从右数第多少个,要是执行lrange numbers -2 -1,就会得到最后两个值。
(4)查询倒数3个:LRANGE KEY_NAME -3 -1
1.1.88.2:63789[1]> LRANGE myList2 -3 -1 1) "c" 2) "b" 3) "a"
这里有两点要注意一下:
(1)如果start索引比stop索引位置靠后(这里说的是位置,不是索引值的大小),则会返回空列表(empty list or set)。
(2)如果stop大于实际的索引范围,则会返回列表最后边的元素。
删除列表中指定值
redis 127.0.0.1:6379> LREM KEY_NAME COUNT VALUE
Redis Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。
COUNT 的值可以是以下几种:
- count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
- count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
- count = 0 : 移除表中所有与 VALUE 相等的值。
返回值是删除值的个数。
删除倒数2个值:
11.1.88.9:63789[1]> LREM mylist -2 hello (integer) 2
删除顺序的1个值:
11.4.88.9:63789[1]> LREM mylist 1 hello (integer) 1
只保留列表中指定的片段
Redis Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
redis 127.0.0.1:6379> LTRIM KEY_NAME START STOP
Ltrim 剪切注意事项:
【1】从左边开始剪切是从:0 开始 ,这样的话可以按照数组下标的方式去获取存储就可以了。0就是第一个元素哦
【2】从右边剪切是从:-1 开始的,-1就是倒数第一个元素哦!
查询所有元素:
12.1.88.2:6389[1]> LRANGE mylist 0 -1 1) "33333333333" 2) "44444444444" 3) "4555555555555" 4) "66666666666" 5) "88888888888" 6) "9999999999"
例如:只截取中间的两个值:
3) "4555555555555" 4) "66666666666"
可以这么做:
11.4.88.209:6389[1]> LTRIM mylist 2 -3 左边第三个元素开始和右边第三个元素开始 OK 11.41.8.29:6389[1]> LRANGE mylist 0 -1 1) "4555555555555" 2) "66666666666" 11.1.88.9:6389[1]>
原始数据:
11.1.8.29:6389[1]> LRANGE mylist 0 -1 1) "4555555555555" 2) "66666666666" 3) "9999999999" 4) "7777777777" 5) "88888888888" 6) "555555555" 7) "4444444444"
只截取前面的5条数据:
11.1.8.209:6389[1]> LTRIM mylist 0 4 // 0~4 刚好5个元素 OK 11.41.88.209:6389[1]> LRANGE mylist 0 -1 //查看所有列表 1) "4555555555555" 2) "66666666666" 3) "9999999999" 4) "7777777777" 5) "88888888888"
利用链表实现文章列表页缓存
通常的文章列表,每次都要访问数据库,数据库压力很大,一个分页条件的不同页面之间数据无法共享。一旦数据库出问题时,整个页面随之无法访问。
怎么办?可以增加memcache缓存。每一页做一个缓存,例如10分钟。但是多页之间,可能你先缓存,我后缓存,数据就会出现不一致的情况。而且每一页的缓存创建都需要访问数据库。如果将所有结果缓存起来,每次读取出整个缓存再分析出分页数据,不仅性能不高,服务器网卡也将承受巨大的流量压力。
而redis的链表功能,能基本完美的解决这些问题。
将mysql查询出的列表的全部文章id都保存到一个链表里,需要访问第N页时,只需要lrange出对应的PAGE_SIZE个文章id,然后再从缓存中读取这PAGE_SIZE个文章的信息。列表就完成了。下次访问的时候,就完全不需要数据库,直到缓存失效。并且一次读取,所有分页都共用该缓存。不仅提高了效率,还保证了分页间的数据一致。文章信息,也再从数据库读取之后,保存到redis中。
对于访问频繁且从数据库读取代价比较大的数据,一旦缓存失效,将有多个并发去请求数据库,给数据库带来很大的压力。这时可以给列表缓存(命名为list)再加个存活缓存(命名为live)。list永不过期,而live存活时间只有10分钟。每次先lrange请求出需要的数据,再检测live是否存在。如果不存在就先重新设置live,然后再从数据库读取列表,重新设置list。这样的好处就是,只有第一个检测到live失效的请求会访问数据库,其他并发请求访问的是缓存数据。
这个方法带来的另一个好处是,即使数据库宕机,列表仍然能正常访问
获取Redis数据批量的保存到Redis中去解析Redis数据的json格式
public function RedisSaveToMysqlJsonAction() { $redis = RedisInstance::getInstance(); $redis->select(1); $redisInfo = $redis->lRange('message01',0,9); $dataLength = $redis->lLen('message01'); $redis->set('dataLength_front',$dataLength); while($dataLength > 20) { try { $this->db->begin(); foreach ($redisInfo as $action) { $sql = "INSERT INTO stream_name (name,createTime,userId,content) VALUES (?, ? ,? ,?)"; $this->db->execute($sql, array( json_decode($action,true)['userName'], json_decode($action,true)['createTime'], json_decode($action,true)['userId'], json_decode($action,true)['content'], )); } $redis->set('message_insert_success', '00000'); $redis->lTrim('message01', 10, -1); $redisInfo = $redis->lRange('message01',0,9); $dataLength = $redis->lLen('message01'); $redis->set('dataLength_backenk', $dataLength); $this->db->commit(); } catch (\Exception $e) { $redis->set('message_catch', json_encode($e)); $this->db->rollback(); } } var_dump($redisInfo); die; }