Redis入门

来源:互联网 发布:南昌金域名都 编辑:程序博客网 时间:2024/06/03 13:35

Redis是一个开源的,使用C语言编写的、支持网络交互的、可基于内存也可持久化的key-value数据库。


1.Redis的持久化

Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。

RDB,简单说就是在不同的时间点,将Redis存储的数据生成快照并存储到磁盘等介质上。

AOF,则是换了一个角度来实现持久化,那就是将Redis执行过的所有写指令记录下来,在下次Redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复。

如果RDB和AOF同时使用,Redis重启的话,则会优先采用AOF方式来进行恢复,这是因为AOF方式的数据恢复完整度更高。

(1)RDB

Redis在进行数据持久化过程中,会先将数据写到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次久化好的文件。正是这种特性,让我们可以随时进行备份,因为快照文件总是完整可用的。对于RDB方式,Redis会单独创建一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了Redis极高的性能。

如果对于数据恢复的完整性不是非常敏感,RDB方式要比AOF更加高效,如果对数据的完整性非常敏感,当Redis故障时,仍然会有近5分钟的数据丢失。

(2)AOF

默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,Redis仍然可以保持很好的处理性能、即使Redis故障,也只会丢失最近1秒的数据。

如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导制日志写入不完整,也没有关系,Redis提供了redis-check-aof工具,可以用来进行日志修复。

Redis提供了AOF文件重写机制,即当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。

在进行AOF重写时,仍然采用先写临时文件,全部完成后再替换的流程。如果直接执行bgrwriteaof命令,那么Redis会生成一个全新的AOF文件。

在重写即将开始之际,Redis会创建一个“重写子进程”,这个子进程会首先读取现有AOF文件,并将其包含的指令进行分析压缩并写到一个临时文件中。与此同时,主工作进程会将新接收到写指令一边累积到内存缓存区中,一边继续写入原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。当“重写子进程“完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。当追加结束后,Redis就会用新的AOF文件来代替旧的AOF文件,之后再有新的写指令,就都会追加新的AOF文件中了。


2. 主从

Redis支持主从同步,而且也支持一主多从以及多级比结构。在主从架构中,从服务器通常被设置为只读模式,这样可以避免从服务器的数据被误修改。但是从服务器仍然可以接受CONFIG等指令,如果必须将从服务器直接暴露到不安全的网络环境中,可以考虑给重要指令进行重命名,来避免被外人执行。

在主从架构中,可以考虑关闭服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能。

Redis的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低Redis的处理性能。从服务顺向主服务器发出SYNC指令,当主服务器接受到此命令后,就会调用BGSAVE指令来创建一个子进程专门进行数据持久化工作,也就是将主服务器的数据写入RDB文件中。在BGSAVE指令执行完成后,主服务器会将持久化好的RDB文件发送给从服务器,从服务器接到此文件后会将其存储到磁盘上,然后再读取到内存中。这个动作完成后,主服务器会将这段时间缓存的写指令再以Redis协议的格式发送给从服务器。


3.事务

(1)MULTI用来组装一个事务

(2)EXEC用来执行一个事务

(3)DISCARD用来取消一个事务

(4)WATCH用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行。支持同时监视多个key。


4.配置

Redis配置文件被分成几大块区域

(1)通用(general)

  • daemonize配置项可以控制Redis的支行形式,默认情况下,Redis并不是以daemon形式来运行的。当以daemon形式运行时,Redis会生成一个pid文件,默认会生成在/var/run/redis.pid,也可以通过pidfile来指定文件生成的位置。
  • 默认情况下,Redis会响应本机所有可用网卡的连接请求,可以通过bind配置项来指定要绑定的IP。
  • Redis默认服务端口是6379,可以通过port配置项来修改,如果端口设置为0的话,Redis便不会监听端口了。
  • Redis还支持unix socket方式来接收请求,可以通过unixsocket配置项来指定unix socket文件路径,并通过unixsocketperm来指定文件的权限。
  • 当一个redis-client一直没有请求发向server端,那以server端有权主动关闭这个连接,可以通过timeout来设置空闲超时时限,0表示永不关闭。
  • TCP连接策略,可以通过tcp-keepalive配置项来进行设置,单位为秒,如果设置为0,则不会进行保活检测。
  • 通过loglevel配置项设置日志等级,共分四级,即debug verbose notice warning
  • 通过logfile配置项来设置文件的生成位置。如果设置为空,则Redis会将日志输出到标准输出。在daemon情况下,日志会被写到/dev/null中。
  • 如果希望日志打印到syslog中,通过syslog-enabled来控制。另外,syslog-ident还可以让你指定syslog里的日志标志。
  • 通过databases可以设置数据库的总数量。数据库编号从0开始。



(2)快照(snapshotting)

  • 如果用户开启了RDB,那么Redis持久化失败时,Redis会停止接受所有的写请求,也可以使用stop-writes-on-bgsave-error来关闭这个功能。
  • 对于存储到磁盘的快照,可以设置是否进行压缩存储,如果是的知,Redis会采用LZF算法进行压缩。可以使用rdbcompression配置项来关闭这个功能。
  • 在存储快照后,可以使用CRC64算法来进行数据检验,但是这样会增加性能消耗,可以使用rdbchecksum 配置项来关闭此功能。
  • 可以通过dbfilename来设置快照文件的名称。
  • 可以通过dir来设置快照文件存放在路径。

(3)复制(replication)

  • 如果主Redis设置了验证密码的话(使用requirepass来设置),则在从Redis的配置中要使用masterauth来设置检验密码。
  • 通过slave-read-only来设置从Redis是否只读。
  • 只读的从Redis并不适合直接暴露给不可信的客户端,可以使用rename-command指令来将一些可能有破坏办的命令重命名。
  • 从Redis会周期性的向主Redis发PING包,可以通过repl-ping-slave-period指令控制其周期。其超时设置可以通过repl-ping-slave-period设置,不过要确保这个时限比repl-ping-slave-period的值要大。
  • 可以通过repl-disable-tcp-nodelay来设置 主从同步时是否禁用TCP_NODELAY,如果开启了TCP_NODEPLAY,那么主Redis会使用更少的TCP包和更少的带宽来向从Redis传输数据。但是这可能会增加一些同步的延迟,大概会达到40毫秒。
  • 通过repl-backlog-size设置同步队列长度,队列长度(backlog)是主Redis的一个缓冲区,在与从Redis断开连接期间,主Redis会用这个缓冲区来缓存应该发给从Redis的数据。这样的话,当从Redis重新连接上之后,就不必重新全量同步数据。
  • 如果主Redis等待了一段时间之后,还是无法连接上从Redis,那么缓冲队列中的数据将被清理掉,这个时间可以通过repl-backlog-ttl设置,如果设置为0,则表示永不清理。
  • 在众多的从Redis中可以设置优先级,在主Redis不正常的情况下,优先级高的从Redis将会升级为主Redis,slave-priority,如果设置为0,这个从Redis永远也不会被选中。
  • 假如主Redis发现有超过M个从Redis的连接延时超过N秒,那么主Redis就停止接受外来的写请求。如果min-slaves-to-write 3, min-slaves-max-lag 10,那么有3个从Redis的连接延迟超过10秒,那么主Redis就不再接爱外部的写请求。上述两个配置中有一个被置为0,则这特性将被关闭。

(4)安全(security)

  • requirepass 可以设置密码验证。
  • rename-command如果把命令改为空安符串,就是禁用掉CONFIG命令。

(5)限制(limits)

  • maxclients,设置Redis同时可以与多少个客户端进行连接,当你无法设置进程文件句柄限制时,Redis会设置为当前的文件句柄限制值减去32,因为Redis会为自身处理逻辑留一些句柄。
  • maxmemoery <bytes> ,设置Redis可以使用的内存理,一旦到达内存使用上限,Redis会尝试移除内部数据,移除规则可以通过maxmemory-policy来指定。
  • maxmemory-policy ,可以是volatile-lru(LRU算法移除过期集合中的key)、allkey-lru(使用LRU算法移除key)、volatile-random(在过期集合中移除随机的key)、allkeys-random(移除随机的key)、volatile-ttl(移除那此TTL值最小的key)、noeviction(不进行移除,只是返回错误信息)

(6)追加模式(append only mode)

  • appendfilename,设置aof文件的名称 。
  • appendfsync,aof缓存的模式(no=让操作系统自行决定,always=每次写请求,everysec=每秒)
  • no-appendsync-on-rewrite,如果后台持久化需要一个很大的IO操作,那么Redis可能会在fsync调用时卡住,使用这引配置项。
  • auto-aof-rewrite-percentage和auto-aof-rewrite-min-size,用于Redis自动启动重写。

(7)LUA脚本(lua scripting)

  • lua-time-limit(ms),设置lua脚本的最大运行时间,如果设置为0或负数,则不会有时间限制。

(8)慢日志(slow log)

慢日志是用于Redis记录那些超过指定查询时间的日志,执行的时间不包括和客户羰的IO操作和响应时间等,而只是Redis执行命令的时间。针对慢日志,可以设置两个参数,一个是执行时长,另一个是长度。slowlog-log-slower-than, slow-max-len。

(9)事件通知(event notification)

Redis支持”主配置文件中引入外部配置文件“

include /path/to/other.conf

5.Redis数据类型

1.String

这是简单的key-value类型,value其实不仅是String,也可以是数字。

应用场景:可以完全实现目前Memcached的功能,并且效率更高。

  • 获取字符串长度。
  • 往字符串append内容。
  • 设置和获取字符串的某一段内容。
  • 设置及获取字符串的某一位(bit)
  • 批量设置一系列字会串的内容。
实现方式:String在Redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr、decr等操作进会转成数值进行计算,此时redisObject的encoding字段为int.

2.Hash

需要注意,Redis提供了hgetall可以直接取得全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历可能会比较耗时,而令其它客户端的请求完全不响应。

实现方式:Redis Hash对应的Value内部实现就是一个HashMap,实际这里会有两种不同实现,这个Hash的成员比少时Redis为节省内存会采用类似一维数组的方式秋紧凑存储,而不会采用真正的HashMap结构,对应的redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。

3.List

应用场景:列表和队列。

Redis的list的实现为一个双向链表,即可以支持查找和遍历,更方便操作,不过带了部分额外的内存开销。

4.Set

应用场景:排重列表。

实现方式:set的内部实现是一个value永远为null的HashMap,实际就是通过计算hash方式来快速排重。

5.Sort Set

可以通过用户额外提供一个优先级(score)的参数来为成员排序。

实现方式:内部使用HashMap和跳表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳表里存放的是所有成员,使用跳表的结构可以获得比较高的查找效率,并且在实现上比较简单。

6.Pub/Sub

就是发布和订阅,在Redis中,可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行消息发布后,所有订阅它的客户端都会收到相应的消息。



6.Redis实际应用场景

(1)显示最新的项目列表

LPUSH lastest.comments <ID>

LTRIM latest.comments 0 5000可以裁剪为指定的长度。

(2)删除和过滤

可以使用LREM来删除评论。

(3)排行榜相关

模式是这样的,每次获得新得分时,ZADD leaderboard <score> <username>

得到前100名高分用户:ZREVRANGE leaderboard 0 99

用户的全球排名:ZRANK leaderboard <username>

(4)计数

Redis是一个很好的计数器,有了原子递增,可以放心的加上各种计数,用GETSET重置,或者是让它们过期。






0 0
原创粉丝点击