redis简介
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的安装,配置等基本参数,基本用法(PHP)
mac安装redis
#安装redis
brew install redis
#启动redis
redis-server
#测试redis是否启动
redis-cli ping
#连接本机redis
redis-cli
# Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize yes
# 当redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile /var/run/redis.pid
# 默认情况下,redis会响应本机所有可用网卡的连接请求。当然,redis允许你通过bind配置项来指定要绑定的IP
bind 192.168.1.2 10.8.4.2
# redis的默认服务端口是6379,你可以通过port配置项来修改。如果端口设置为0的话,redis便不会监听端口了,可以通过unixsocket配置项来指定unix socket文件的路径,并通过unixsocketperm来指定文件的权限:unixsocket /tmp/redis.sockunixsocketperm 755
port 6379
## TCP 监听的最大容纳数量,在高并发的环境下,你需要把这个值调高以避免客户端连接缓慢的问题。Linux 内核会一声不响的把这个值缩小成 /proc/sys/net/core/somaxconn 对应的值,所以你要修改这两个值才能达到你的预期。
tcp-backlog 511
# 指定在一个 client 空闲多少秒之后服务端关闭连接(0 表示永不关闭)
timeout 0
# TCP连接心跳检测策略,可以通过tcp-keepalive配置项来进行设置,单位为秒,假如设置为60秒,则server端会每60秒向连接空闲的客户端发起一次ACK请求,以检查客户端是否已经挂掉,对于无响应的客户端则会关闭其连接。所以关闭一个连接最长需要120秒的时间。如果设置为0,则不会进行心跳检测
tcp-keepalive 300
#redis支持通过loglevel配置项设置日志等级,共分四级,即debug、verbose、notice、warning。
loglevel notice
# 日志保存目录
logfile /usr/local/redis/logs/redis.log
# 对于redis来说,可以设置其数据库的总数量,假如你希望一个redis包含16个数据库,这16个数据库的编号将是0到15。默认的数据库是编号为0的数据库。用户可以使用select <DBid>来选择相应的数据库
databases 16
# 主要涉及的是redis的RDB持久化相关的配置
save 900 1 # 表示每15分钟且至少有1个key改变,就触发一次持久化
save 300 10 # 表示每5分钟且至少有10个key改变,就触发一次持久化
save 60 10000 # 表示每60秒至少有10000个key改变,就触发一次持久化
#默认情况下,如果 redis 最后一次的后台保存失败,redis 将停止接受写操作,
# 这样以一种强硬的方式让用户知道数据不能正确的持久化到磁盘,
# 否则就会没人注意到灾难的发生
stop-writes-on-bgsave-error yes
# 是否在 dump.rdb 数据库的时候使用 LZF 压缩字符串,压缩会占用CPU资源
rdbcompression yes
# 在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验
rdbchecksum yes
# 我们还可以设置快照文件的名称,
dbfilename dump.rdb
# 设置这个快照文件存放的路径
dir ./
# 当一个 slave 与 master 失去联系,或者复制正在进行的时候,
# slave 可能会有两种表现:
#
# 1) 如果为 yes ,slave 仍然会应答客户端请求,但返回的数据可能是过时,
# 或者数据可能是空的在第一次同步的时候
#
# 2) 如果为 no ,在你执行除了 info he salveof 之外的其他命令时,
# slave 都将返回一个 "SYNC with master in progress" 的错误,
#
slave-serve-stale-data yes
# 你可以配置一个 slave 实体是否接受写入操作。
# 通过写入操作来存储一些短暂的数据对于一个 slave 实例来说可能是有用的,
# 因为相对从 master 重新同步数而言,据数据写入到 slave 会更容易被删除。
# 但是如果客户端因为一个错误的配置写入,也可能会导致一些问题。
slave-read-only yes
# Slaves 在一个预定义的时间间隔内发送 ping 命令到 server 。
# 你可以改变这个时间间隔。默认为 10 秒
repl-ping-slave-period 10
# 我们可以控制在主从同步时是否禁用TCP_NODELAY。如果开启TCP_NODELAY,那么主redis会使用更少的TCP包和更少的带宽来向从redis传输数据。但是这可能会增加一些同步的延迟,大概会达到40毫秒左右。如果你关闭了TCP_NODELAY,那么数据同步的延迟时间会降低,但是会消耗更多的带宽
repl-disable-tcp-nodelay no
# 当 master 不能正常工作的时候,Redis Sentinel 会从 slaves 中选出一个新的 master,
# 这个值越小,就越会被优先选中,但是如果是 0 , 那是意味着这个 slave 不可能被选中
slave-priority 100
# 追加模式
appendonly no
# 追加模式的文件名称
appendfilename "appendonly.aof"
# redis支持三种不同的模式:
# no:不调用fsync()。而是让操作系统自行决定sync的时间。这种模式下,redis的性能会最快。
# always:在每次写请求后都调用fsync()。这种模式下,redis会相对较慢,但数据最安全。
# everysec:每秒钟调用一次fsync()。这是性能和安全的折衷
appendfsync everysec
no-appendfsync-on-rewrite no
# 我们允许redis自动重写aof。当aof增长到一定规模时,redis会隐式调用BGREWRITEAOF来重写log文件,以缩减文件体积。
# redis是这样工作的:redis会记录上次重写时的aof大小。假如redis自启动至今还没有进行过重写,那么启动时aof文件的大小会被作为基准值。
# 这个基准值会和当前的aof大小进行比较。如果当前aof大小超出所设置的增长比例,则会触发重写。另外,你还需要设置一个最小大小,是为了防止在aof很小时就触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
#
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
# 从服务器配置
slaveof 10.8.34.29 6379
# 当master服务设置了密码保护时,slav服务连接master的密码
masterauth redis123
# 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
requirepass redis123
redis持久化
redis支持四种持久化方式,一是 Snapshotting(快照)也是默认方式;二是Append-only file(缩写aof)的方式;三是虚拟内存方式;四是diskstore方式
- RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
- AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF 文件中的命令全部以 Redis
协议的格式来保存,新命令会被追加到文件的末尾。Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF文件的体积不会超出保存数据集状态所需的实际大小。 - Redis 还可以同时使用 AOF 持久化和 RDB 持久化。在这种情况下,当 Redis 重启时,它会优先使用 AOF
文件来还原数据集,因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。 - 你甚至可以关闭持久化功能,让数据只在服务器运行时存在
RDB优点:
- RDB 是一个非常紧凑(compact)的文件,它保存了 Redis
在某个时间点上的数据集。这种文件非常适合用于进行备份:比如说,你可以在最近的 24 小时内,每小时备份一次 RDB
文件,并且在每个月的每一天,也备份一个 RDB 文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
- RDB 非常适用于灾难恢复(disaster
recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。 - RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork
出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。 - RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
RDB缺点:
- 如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。虽然 Redis 允许你设置不同的保存点(save
point)来控制保存 RDB 文件的频率,但是,因为RDB 文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此你可能会至少5 分钟才保存一次 RDB 文件。在这种情况下,一旦发生故障停机,你就可能会丢失好几分钟的数据。 - 每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。在数据集比较庞大时,
fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端;如果数据集非常巨大,并且 CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。虽然 AOF 重写也需要进行 fork() ,但无论 AOF重写的执行间隔有多长,数据的耐久性都不会有任何损失。
AOF优点:
- 使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无
fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。AOF 的默认策略为每秒钟 fsync一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)。 - AOF 文件是一个只进行追加操作的日志文件(append only log),因此对 AOF 文件的写入不需要进行 seek
,即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等),redis-check-aof工具也可以轻易地修复这种问题。 - Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写:重写后的新 AOF
文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为 Redis 在创建新 AOF文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。而一旦新 AOF文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。 - AOF 文件有序地保存了对数据库执行的所有写入操作,这些写入操作以 Redis 协议的格式保存,因此 AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export) AOF文件也非常简单:举个例子,如果你不小心执行了 FLUSHALL 命令,但只要 AOF 文件未被重写,那么只要停止服务器,移除 AOF文件末尾的 FLUSHALL 命令,并重启 Redis ,就可以将数据集恢复到 FLUSHALL 执行之前的状态
AOF 的缺点:
- 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。在一般情况下,每秒 fsync 的性能依然非常高,而关闭 fsync可以让 AOF 的速度和 RDB 一样快,即使在高负荷之下也是如此。不过在处理巨大的写入载入时,RDB可以提供更有保证的最大延迟时间(latency)。
- AOF 在过去曾经发生过这样的 bug :因为个别命令的原因,导致 AOF
文件在重新载入时,无法将数据集恢复成保存时的原样。(举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug)测试套件里为这种情况添加了测试:它们会自动生成随机的、复杂的数据集,并通过重新载入这些数据来确保一切正常。虽然这种 bug 在 AOF文件中并不常见,但是对比来说,RDB 几乎是不可能出现这种 bug 的
RDB快照原理:
在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。对 Redis 进行设置,让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时,自动保存一次数据集
save 900 1 # 900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10 # 300 秒内如果至少有 10 个 key 的值变化,则保存
save 60 10000 # 60 秒内如果至少有 10000 个 key 的值变化,则保存
当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:
- Redis 调用 fork() ,同时拥有父进程和子进程。
- 子进程将数据集写入到一个临时 RDB 文件中。
- 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益
AOF持久化策略及原理:
你可以配置 Redis 多久才将数据 fsync 到磁盘一次。
- 每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
- 每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
- 从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
推荐(并且也是默认)的措施为每秒 fsync 一次,这种 fsync 策略可以兼顾速度和安全性
以下是 AOF 重写的执行步骤:
- Redis 执行 fork() ,现在同时拥有父进程和子进程。
- 子进程开始将新 AOF 文件的内容写入到临时文件。
- 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF
文件的末尾:这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。 - 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
- 现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
redis集群介绍
redis的存储数据结构
redis使用场景
1.取最新N个数据的操作
比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取
- 使用LPUSH latest.comments<ID>命令,向list集合中插入数据
- 插入完成后再用LTRIM latest.comments 0 5000命令使其永远只保存最近5000个ID
- 然后我们在客户端获取某一页评论时可以用下面的逻辑(伪代码)
FUNCTION get_latest_comments(start,num_items):
id_list = redis.lrange("latest.comments",start,start+num_items-1)
IF id_list.length < num_items
id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
END
RETURN id_list
END
如果你还有不同的筛选维度,比如某个分类的最新N条,那么你可以再建一个按此分类的List,只存ID的话,Redis是非常高效的。
2.排行榜应用,取TOP N操作
这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。
3.需要精准设定过期时间的应用
比如你可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。
4.计数器应用
Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。
5.Uniq操作,获取某段时间所有数据排重值
这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。比如微博共同关注好友
6.实时系统,反垃圾系统
通过上面说到的set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。没有做不到,只有想不到。
7.Pub/Sub构建实时消息系统
Redis的Pub/Sub系统可以构建实时的消息系统,比如很多用Pub/Sub构建的实时聊天系统的例子。
8.构建队列系统
使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。
9.缓存
这个不必说了,性能优于Memcached,数据结构更多样化。配合数据库缓存数据
参考资料:
http://blog.csdn.net/is_zhouf…
配置参考:
http://blog.csdn.net/a1282379…
http://www.jianshu.com/p/7970…
http://www.cnblogs.com/kreo/p…
http://doc.redisfans.com/ redis命令查询
http://blog.nosqlfan.com/html… 使用场景