10.Redis编程入门

本主题主要是Redis的基本入门,包含内容:
  1. Redis的安装与配置
  2.Redis的命令行操作
  3.Redis Python编程操作编程

一、下载与安装

1. 下载

1.1. 下载地址:

  | - https://redis.io/download

Redis下载

1.2. 下载的是tar压缩文件

  redis-5.0.3.tar
  下面是下载的截图

redis-5.0.3.tar,如果需要集群版本,应该下载stable版本

2. 安装

2.1. 解压缩指令

使用tar压缩工具解压缩:
  tar -xf redis-5.0.3.tar

yangqiangdeMacBook-Pro:Downloads yangqiang$ tar -xf redis-5.0.3.tar
Redis解压缩目录

编译

进入解压缩目录,使用make执行编译:


Redis编译

2.2. 安装

执行make install实现安装


Redis安装

二、配置

1. 配置服务目录与文件

1.1. 配置目录

在/usr/local/目录下(也可以在其他目录下)创建redis服务器目录,我在我的默认用户的住目录下建立服务器目录:

建立服务器安装目录

创建三个目录:
  | - bin:用来存放执行文件,包含服务器程序,客户程序等。
  | - etc:用来存放配置文件。
  | - db:用来存放数据库文件。

三个存放目录

1.2. 拷贝执行与配置文件到服务目录

cp ~yangqiang/Downloads/redis-5.0.3/src/mkreleasehdr.sh ./bin
cp ~yangqiang/Downloads/redis-5.0.3/src/redis-benchmark  ./bin/
cp ~yangqiang/Downloads/redis-5.0.3/src/redis-cli  ./bin/
cp ~yangqiang/Downloads/redis-5.0.3/src/redis-server ./bin/
cp ~yangqiang/Downloads/redis-5.0.3/redis.conf   ./etc/
核心执行程序

2. 修改配置文件

2.1. 配置IP地址

配置IP地址

2.2. 配置端口

配置端口

2.3. 配置后台模式

配置后台模式

2.4. 配置进程锁文件

配置进程锁文件

2.5. 配置数据库数量

默认是0,可以使用命令行语句select < dbid > 选择数据库。

配置数据库数量

2.6. 数据库更新保存条件

其中第一个是秒数,第一个是改变次数,满足这些条件的任何一个就会自定保存或者更新。

数据库更新条件

2.7. 配置数据库数据是否压缩

压缩配置

2.8. 配置数据库文件名

配置数据库文件名

2.9. 配置数据库的存放目录

数据库存放目录

2.10. 配置登录口令

配置登录口令

三、启动服务器

启动指令:

./bin/redis-server ./etc/redis.conf 

前面是服务器程序,参数是配置文件。

控制台下启动效果如下:


服务器启动效果

四、客户端使用

1. 客户端命令行帮助

客户端帮助

2. 启动客户端

客户端启动

3. 获取客户端使用帮助

连接上服务器后,使用help指令,可以获取使用帮助

服务器指令帮助

注意:
  其中help <tab>是help后不停按tab键,会依次出现各种命令。
  help @命令分组 获取每个命令组的帮助。
  
  命令与SQL指令一样,不区分大小写。
  
  为了方便,下面介绍常见的操作。

4. 客户端指令分组

4.1. 连接操作相关的命令

命令 说明
ping 测试连接是否存活如果正常会返回pong
echo 打印
select 切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值
quit 关闭连接(connection)
auth 简单密码认证

4.2. 服务端相关命令

命令 说明
time 返回当前服务器时间
client list 返回所有连接到服务器的客户端信息和统计数据 参见http://redisdoc.com/server/client_list.html
client kill ip:port 关闭地址为 ip:port 的客户端
save 将数据同步保存到磁盘
bgsave 将数据异步保存到磁盘
lastsave 返回上次成功将数据保存到磁盘的Unix时戳
shundown 将数据同步保存到磁盘,然后关闭服务
info 提供服务器的信息和统计
config resetstat 重置info命令中的某些统计数据
config get 获取配置文件信息
config set 动态地调整 Redis 服务器的配置(configuration)而无须重启,可以修改的配置参数可以使用命令 CONFIG GET * 来列出
config rewrite Redis 服务器时所指定的 redis.conf 文件进行改写
monitor 实时转储收到的请求
slaveof 改变复制策略设置

4.3. 发布订阅相关命令

命令 说明
psubscribe 订阅一个或多个符合给定模式的频道 例如psubscribe news.* tweet.*
publish 将信息 message 发送到指定的频道 channel 例如publish msg "good morning"
pubsub channels 列出当前的活跃频道 例如PUBSUB CHANNELS news.i*
pubsub numsub 返回给定频道的订阅者数量 例如PUBSUB NUMSUB news.it news.internet news.sport news.music
pubsub numpat 返回客户端订阅的所有模式的数量总和
punsubscribe 指示客户端退订所有给定模式。
subscribe 订阅给定的一个或多个频道的信息。例如 subscribe msg chat_room
unsubscribe 指示客户端退订给定的频道。

4.4. 对KEY操作的命令

命令 说明
exists(key) 确认一个key是否存在
del(key) 删除一个key
type(key) 返回值的类型
keys(pattern) 返回满足给定pattern的所有key
randomkey 随机返回key空间的一个
keyrename(oldname, newname) 重命名key
dbsize 返回当前数据库中key的数目
expire 设定一个key的活动时间(s)
ttl 获得一个key的活动时间
move(key, dbindex) 移动当前数据库中的key到dbindex数据库
flushdb 删除当前选择数据库中的所有key
flushall 删除所有数据库中的所有key

4.5. 对String操作的命令

命令 说明
set(key, value) 给数据库中名称为key的string赋予值value
get(key) 返回数据库中名称为key的string的value
getset(key, value) 给名称为key的string赋予上一次的value
mget(key1, key2,…, key N) 返回库中多个string的value
setnx(key, value) 添加string,名称为key,值为value
setex(key, time, value) 向库中添加string,设定过期时间time
mset(key N, value N) 批量设置多个string的值
msetnx(key N, value N) 如果所有名称为key i的string都不存在
incr(key) 名称为key的string增1操作
incrby(key, integer) 名称为key的string增加integer
decr(key) 名称为key的string减1操作
decrby(key, integer) 名称为key的string减少integer
append(key, value) 名称为key的string的值附加value
substr(key, start, end) 返回名称为key的string的value的子串

4.6. 对List操作的命令

命令 说明
rpush(key, value) 在名称为key的list尾添加一个值为value的元素
lpush(key, value) 在名称为key的list头添加一个值为value的 元素
llen(key) 返回名称为key的list的长度
lrange(key, start, end) 返回名称为key的list中start至end之间的元素
ltrim(key, start, end) 截取名称为key的list
lindex(key, index) 返回名称为key的list中index位置的元素
lset(key, index, value) 给名称为key的list中index位置的元素赋值
lrem(key, count, value) 删除count个key的list中值为value的元素
lpop(key) 返回并删除名称为key的list中的首元素
rpop(key) 返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout) lpop命令的block版本。
brpop(key1, key2,… key N, timeout) rpop的block版本。
rpoplpush(srckey, dstkey) 返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

4.7. 对Set操作的命令

命令 说明
sadd(key, member) 向名称为key的set中添加元素member
srem(key, member) 删除名称为key的set中的元素member
spop(key) 随机返回并删除名称为key的set中一个元素

smove(srckey, dstkey, member) :移到集合元素
scard(key) |返回名称为key的set的基数
sismember(key, member) |member是否是名称为key的set的元素
sinter(key1, key2,…key N) |求交集
sinterstore(dstkey, (keys)) |求交集并将交集保存到dstkey的集合
sunion(key1, (keys)) |求并集
sunionstore(dstkey, (keys)) |求并集并将并集保存到dstkey的集合
sdiff(key1, (keys)) |求差集
sdiffstore(dstkey, (keys)) |求差集并将差集保存到dstkey的集合
smembers(key) |返回名称为key的set的所有元素
srandmember(key) |随机返回名称为key的set的一个元素

4.8. 对Hash操作的命令

命令 说明
hset(key, field, value) 向名称为key的hash中添加元素field
hget(key, field) 返回名称为key的hash中field对应的value
hmget(key, (fields)) 返回名称为key的hash中field i对应的value
hmset(key, (fields)) 向名称为key的hash中添加元素field
hincrby(key, field, integer) 将名称为key的hash中field的value增加integer
hexists(key, field) 名称为key的hash中是否存在键为field的域
hdel(key, field) 删除名称为key的hash中键为field的域
hlen(key) 返回名称为key的hash中元素个数
hkeys(key) 返回名称为key的hash中所有键
hvals(key) 返回名称为key的hash中所有键对应的value
hgetall(key) 返回名称为key的hash中所有的键(field)及其对应的value

5. 设置密码

设置密码的命令是属于服务器组,其中密码设置属于redis.conf文件中的配置。

密码设置帮助

可以使用config get指令得到配置参数。
也可以使用config set指令修改配置参数。(当然可以直接编辑redis.conf文件来设置登录密码)

下面首先查看登录密码,然后设置登录密码,然后再登录,登录后就可以查看登录密码了。


密码设置与登录

强烈推荐登录方式不要使用命令行参数,而是使用AUTH指令。


建议不要使用命令行设置登录密码

6. 选择当前数据库

使用select 指令,指定数据库编号即可。

切换数据库

7. 数据库操作

7.1. 数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及sorted set(有序集合)。

7.2. string数据操作

string 是 redis 最基本的类型,一个 key 对应一个 value;string 类型的值最大能存储 512MB。
string 类型是二进制安全的,就是redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

127.0.0.1:6379> help SET

  SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string

SET参数说明:
  | - EX指定过期时间单位为:秒
  | - PX指定过期时间单位为:毫秒
  | - NX key不存在才执行指令
  | - XX key存在才会更新

String类型操作

过期时间一到,从内存数据消失。

7.3. Hash数据操作

Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
每个 hash 可以存储 232 -1 键值对(40多亿)。

127.0.0.1:6379> help hmset

  HMSET key field value [field value ...]
  summary: Set multiple hash fields to multiple values
  since: 2.0.0
  group: hash

127.0.0.1:6379> 

hash类型操作

获取所有keys与values:


回去所有的keys与values

7.4. List数据操作

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

List数据类型操作

7.5. Set数据操作

Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

Set类型操作

7.6. sorted set数据操作

Redis zset(sorted set) 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。

Sorted-Set类型操作

7.7. 查看key并删除key

使用keys命令与del命令


Keys操作

7.8. 事务处理

事务命令 说明
DISCARD 取消事务,放弃执行事务块内的所有命令。
EXEC 执行所有事务块内的命令。
MULTI 标记一个事务块的开始。
UNWATCH 取消 WATCH 命令对所有 key 的监视。
WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
事务操作

五、python访问Redis数据库

1. 安装redis模块

使用命令

yangqiangdeMacBook-Pro:bin yangqiang$ pip install redis
Collecting redis
  Downloading https://files.pythonhosted.org/packages/f1/19/a0282b77c23f9f9dbcc6480787a60807c78a45947593a02dbf026636c90d/redis-3.1.0-py2.py3-none-any.whl (63kB)
    100% |████████████████████████████████| 71kB 103kB/s 
Installing collected packages: redis
Successfully installed redis-3.1.0

Redis模块安装

2. redis模块帮助

使用help可以获取redis模块帮助文档


Redis模块的帮助

3. redis模块核心API

Redis类负责用户客户端调用的封装,其成员基本上对用Redis客户端的所有操作指令。
Connection负责连接Redis服务器。
其他还有负责分布式锁的Lock等,Sentinel负责集群客户端调用封装等。

4. 单一连接

直接使用Redis连接Redis服务器,redis.client.Redis类构造器如下:

__init__(self, host='localhost', port=6379, db=0, password=None, socket_timeout=None, socket_connect_timeout=None, socket_keepalive=None, socket_keepalive_options=None, connection_pool=None, unix_socket_path=None, encoding='utf-8', encoding_errors='strict', charset=None, errors=None, decode_responses=False, retry_on_timeout=False, ssl=False, ssl_keyfile=None, ssl_certfile=None, ssl_cert_reqs='required', ssl_ca_certs=None, max_connections=None)
# coding = utf-8
import redis.client
redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
print(redis.keys(pattern='*'))

[b'telno', b'key2', b'friends', b'courses', b'key1']

5. 连接池

连接池redis.connection.ConnectionPool的构造器:

__init__(self, connection_class=<class 'redis.connection.Connection'>, max_connections=None, **connection_kwargs)
# coding = utf-8
import redis.client
import redis.connection
pools = redis.connection.ConnectionPool(
    connection_class=redis.connection.Connection,
    max_connections=10,
    host='127.0.0.1',
    port=6379,
    db=0,
    password='yq123456')
redis = redis.client.Redis(connection_pool=pools)
print(redis.keys(pattern='*'))

[b'telno', b'key2', b'friends', b'courses', b'key1']

6. 数据库操作

数据库操作基本上对应redis-cli客户端的指令。

# coding = utf-8
import redis.client
redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
if redis.set(name='py_user', value='Jack'):
    print('执行成功')

if redis.save():
    print('执行成功')



执行成功
执行成功

7. 事务操作

一般来说,事务有四个性质称为ACID,分别是原子性,一致性,隔离性和持久性。
  a)原子性atomicity:redis事务保证事务中的命令要么全部执行要不全部不执行。有些文章认为redis事务对于执行错误不回滚违背了原子性,是偏颇的。
  
  b)一致性consistency:redis事务可以保证命令失败的情况下得以回滚,数据能恢复到没有执行之前的样子,是保证一致性的,除非redis进程意外终结。
  
  c)隔离性Isolation:redis事务是严格遵守隔离性的,原因是redis是单进程单线程模式,可以保证命令执行过程中不会被其他客户端命令打断。
  
  d)持久性Durability:redis事务是不保证持久性的,这是因为redis持久化策略中不管是RDB还是AOF都是异步执行的,不保证持久性是出于对性能的考虑。
  

在Redis中事务有专门的指令,但在Python实现中,通过Pipeline类实现事务相关指令。


__init__(self, connection_pool, response_callbacks, transaction, shard_hint)

获取通过Redis对象的ipieline函数返回Pipeline对象


Redis.pipeline(self, transaction=True, shard_hint=None)

pipeline 也可以保证缓冲的命令组做为一个原子操作。缺省就是这种原子模式。
要使用命令缓冲,但禁止pipeline 的原子操作属性,可以关掉 transaction=False。

7.1. 提交事务

# coding = utf-8

import redis.client
redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
pipeline = redis.pipeline(transaction=True)  # 参数指定是否每个指令后自动提交事务。
pipeline.multi()
pipeline.set(name='py_user', value='Jack')
if pipeline.execute():
    print('提交事务成功')

提交事务成功
# coding = utf-8

import redis.client
import redis.connection
pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks=[]
)
pipe.multi()
pipe.set(name='py_user', value='Jack')
pipe.set(name='linux_user',value='root')
if pipe.execute():     # 提交事务
    print('事务提交成功!')
事务提交成功!

7.2. 回滚(放弃)事务

  
注意:
  Redis与mysql中事务不同,在redis事务遇到执行错误的时候,不会进行回滚,而是简单的越过了,并保证其他的命令正常执行。这点可以通过上面的程序观察到这个设计效果。
  
  在Python代码中,执行错误的命令的异常会被扑捉,并在execute函数的返回值列表中。

# coding = utf-8

import redis.client
import redis.connection
pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks=[]
)
pipe.multi()
pipe.set(name='py_user', value='Jack')
pipe.set(name='linux_user',value='root')
# pipe.execute()
pipe.reset()   # 取消事务

注意:
  reset会释放占用的连接,如果使用连接池,则连接会返回到连接池。

7.3. watch与unwatch的使用

  
  在redis-cli终端中,WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。
  
  如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 WATCH中指定的key的值, 那么程序的事务就会抛出异常 redis.WatchError。抛出异常事务自动取消,需要重新调用MULTI指令。
  
  下面例子运行的时候,在睡眠20秒后指定EXEC,在这期间内,可以在另外客户端修改key为py_user的值,当睡眠20秒后,会抛出异常。(在睡眠中,不会中断睡眠抛出异常,这个与其他编程有差异)
  
  一般对事务处理模式,最好开启监听机制,这样可以提供更好的原子操作。一旦异常抛出,可以反复执行,直到成功为止。

# coding = utf-8

import redis
import redis.connection
import time
pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks=[]
)
try:
    pipe.watch('py_user',)
    pipe.multi()
    pipe.set(name='py_user', value='Jack')
    time.sleep(20)
    pipe.set(name='linux_user', value='root')
    pipe.execute()
except redis.WatchError as e:
    print(e)
    # 异常抛出的时候,事务被自动取消(注意睡眠期间不会触发异常事件)
    pipe.reset()

Watched variable changed.

7.4. Redis类中transaction函数的使用

  
  上面使用watch来观察key的值被其他客户改变,一般为了防止数据脏,会采用循环方式,Redis类提供了transaction函数来处理这种麻烦。
  
  下面代码,可以在其他客户端改变,会看到print("睡眠")执行两次,直到处理并事务提交成功。

# coding = utf-8
import redis.connection
import time
r = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')


def my_cb(pipe_):
    pipe_.multi()
    pipe_.set(name='py_user', value='Jack-Hello')
    print("睡眠")
    time.sleep(5)
    pipe_.set(name='linux_user', value='root')
    if pipe_.execute():
        print("提交成功")
    else:
        print("提交失败")


r.transaction(my_cb, 'py_user')

睡眠
睡眠
提交成功





[]

8. Pipeline类命令执行回调实现

  Pipeline类的构造器中可以指定对命令执行结果返回的回调,这样可以每个命令被执行就可以及时响应,而不是处理execute的返回结果。
  回调函数至少传递一个参数,如果有withscores这样的参数,可能返回多个参数。

# coding = utf-8

import redis
import redis.connection
import time


# 返回每个命名执行的结果
def my_call(*p):
    print(*p)


pool = redis.connection.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, db=0, password='yq123456')
pipe = redis.client.Pipeline(
    connection_pool=pool,
    transaction=True,
    shard_hint=None,
    response_callbacks={'SET': my_call}
)
pipe.multi()
pipe.set(name='py_user', value='Jack')
pipe.set(name='linux_user', value='root')
pipe.execute()    # 因为有回调,所以,这个函数返回是None。


b'OK'
b'OK'





[None, None]

9. 订阅与发布

订阅与发布是一种消息通信机制。包含两个行为:
   | - 订阅:SUBSCRIBE channel [channel ...]
   | - 发布:PUBLISH channel message
  
当然可以退订。
   |- 退订:UNSUBSCRIBE [channel [channel ...]]
同时提供模式匹配指令:
   |- PSUBSCRIBE pattern [pattern ...]
   |- PUNSUBSCRIBE [pattern [pattern ...]]
查看订阅状态:
   |- PUBSUB subcommand [argument [argument ...]]

9.1. 订阅消息

使用SUBSCRIBE命令订阅消息:

消息订阅

9.2. 发布消息

使用PUBLISH发布消息:


消息发布

9.3. 查看订阅发布状态

9.3.1. 获取帮助

使用PUBSUB HELP命令获取完整的帮助:


消息状态查看指令帮助

9.3.2. 查看订阅状态

注意:
  NUMPAT是采用模式订阅的数量。
  NUMSUB是多某个频道德订阅数量。

消息状态查看操作

9.4. 使用python程序订阅消息

订阅消息需要使用订阅发布对象class 'redis.client.PubSub'。
调用handle_message可以把订阅的响应结构解析成一个字典结构。

# coding = utf-8
import redis.client

redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
sub_pub = redis.pubsub()
print(sub_pub, type(sub_pub))

sub_pub.subscribe('mychannel')

result = sub_pub.parse_response()
print('订阅操作:', result)
result = sub_pub.parse_response()
message = sub_pub.handle_message(result)
print('订阅的消息:', result, message['data'])

<redis.client.PubSub object at 0x106c5e940> <class 'redis.client.PubSub'>
订阅操作: [b'subscribe', b'mychannel', 1]
订阅的消息: [b'message', b'mychannel', b'this is a test message'] b'this is a test message'

9.5. 使用python程序发布消息

# coding = utf-8
import redis.client

redis = redis.client.Redis(host='127.0.0.1', port=6379, db=0, password='yq123456')
redis.publish('mychannel','this is a test message')

4

六、附录

  Redis还有一些其他连接快捷方式,我们采用比较常规的方式介绍。
  Redis还支持集群,后面单独介绍集群的配置与Python编程的一些基本概念。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 原帖地址:https://www.jianshu.com/p/2f14bc570563 redis概述 Redis...
    onlyHalfSoul阅读 2,154评论 0 28
  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,958评论 2 27
  • 文章已经放到github上 ,如果对您有帮助 请给个star[https://github.com/qqxuanl...
    尼尔君阅读 2,280评论 0 22
  • 【本教程目录】 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动r...
    徐猿猿阅读 1,863评论 0 35
  • redis是什么 redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Valu...
    烨枫_邱阅读 765评论 0 6