转载--日志

问题概述

在分布式系统中,宕机是需要考虑的重要组成部分。日志技术是宕机恢复的重要技术之一。日志技术应用广泛,早些更是广泛应用在数据库设计实现中。本文先介绍基本原理概念,最后通过redis介绍生产环境中的实现方法。

Redo Log

数据库设计中,需要满足ACID,尤其是在支持事务的系统中。当系统遇到未知错误时,可以恢复到一个稳定可靠的状态。有一个很简单的思路,就是记录所有对数据库的写操作日志。那么一旦发生故障,即使丢失掉内存中所有数据,当下一次启动时,通过复现已经记录的数据库写操作日志,依然可以回到故障之前的状态(如果在写操作作日志的时候发生故障,那么这次数据库操作失败)。

操作流程简单如下(假设每次数据变化,都提交):

  1. 更新的操作方式依次记录到磁盘日志文件。
  2. 更新内存中的数据。
  3. 返回更新成功结果。

恢复流程如下

  1. 读取日志文件,依次修改内存中的数据。

优点:

  1. 日志文件有序,可以通过append的方式写入磁盘,性能很高。
  2. 简单可靠,应用广泛。可以把内存中的数据,做备份在磁盘中。

缺点:

  1. 使用时间一长,恢复宕机的时间很慢。

解决方法

先具体化下,如果我们内存中保留一个a的值,记录了写操作比如 a = 4; a++; a--; 当这些操作上千万、亿之后,恢复非常慢。甚至可能最后一条就是a=0,按照之前的算法,我们却跑了很长时间。

那么根据这个场景,很容易想到一个解决方案。

操作流程:

  1. 日志文件记录begin check point
  2. 在某个时刻,把内存中的数值,直接snapshot或dump到磁盘上.(比如直接记录a=4)
  3. 日志文件记录end check point

恢复流程:

1.扫描日志文件,找到最后的end check point中配对的begin check point。
2.读入dump文件。
3.依次回放记录的日志操作。

优点:

  1. 应用广泛,包括 mysql,oracle。

一些棘手的问题:

  1. 在做snapshot的时候,往往不能停止数据库的服务,那么很可能记录了begin check point之后的日志。那么在重新load begin check point之后的日志时,最后恢复的数据很有可能不对。比如我们记录的是a++这样的日志, 那么重复一条日志,就会让a的值加1。反之如果我们记录是幂等的,比如一直是 a=5 这种操作,那么就对最后结果没有影响。很显然,设计幂等操作系统很麻烦。

  2. 设计一个支持snapshot的内存数据结构,也比较麻烦。

典型的是通过copy-on-write机制。和操作系统中的概念一样。当这个数据结构被修改,就创建一份真正的copy。老数据增加一份dirty flag。如果没有修改就继续使用之前的内存。这样在做snapshot的时候,保证我们的dump数据是begin check point这个时刻的数据。显然这个也比较麻烦。

还有一种支持snapshot的思路是begin check point后,不动老的数据。内存中的数据在新的地方,日志也写在新的地方。最后在end check point做一次merge。这个实现起来简单,但是内存消耗不小。

Redis是如何解决日志问题的

Redis 是一个基于内存的database,不同于memcached,他支持持久化。另外由于redis处理client request 和 response 都是在一个thread里面,也没有抢占式的调度系统,核心业务都是按照event loop顺序执行,而磁盘写日志又开销很大,所以redis实现日志功能做了很多优化。并且提供2种持久化方案。我们需要在不同的场景下,采用不同的方式配置。

snapshotting

某个时刻,redis会把内存中的所有数据snapshot到磁盘文件。更通俗的说法是fork一个child process,把内存中的数据序列化到临时文件,然后在main event loop 中原子的更换文件名。redis,利用了操作系统VM的copy-on-write机制,在不阻塞主线程的情况下,利用子进程和父进程共享的data segment实现snapshot。具体是代码实现在rdb.c, function at rdbSaveBackground

优点:

  1. 简单可靠,如果database 不大,执行的效果非常好。

缺点:

1.如果database size 很大,每一次snapshot时间非常长。不得不配置大的间隔,提高了宕机时数据丢失的风险。
为了解决上面的问题,redis增加了AOF。

Append Only File(AOF)

在database术语中,也被叫做WAL。如果开启的AOF的配置,redis会记录所有写操作到日志文件中。那么redis同样会遇到之前我们提到过的问题。

  1. 即便是追加写,磁盘的操作依然比内存慢好几个数量级,频繁的操作容易产生瓶颈。
  2. 如果数据量操作频繁,会产生大量的重复日志数据,导致恢复时间太长。比如记录一条微博的浏览量,会记录大量重复的+1日志。

那么redis是如何解决的呢?

  1. 文件写操作消耗的时间很长,redis会先把记录日志写在内存buffer中,在每一次event loop 结束之后,根据配置判断是否做写操作。每个buffer的大小有限制,这样每次写操作时间不会太长。
  2. 即便是调用write操作,OS并没有立即写入磁盘,redis 同样提供了一些方案决定刷新OS IO buffer的时机(1秒、从不、每次)。
  3. redis 提供一种AOF重写的方式rewriteAppendOnlyFile来处理AOF文件过大情况。

前面我们知道了,这种check point的机制还是比较麻烦的。那么redis是怎么设计的呢?

rewrite

  1. 为了避免加锁,redis 依然创建了一个child process,利用VM的copy-on-write,共享数据。同时保证主线程依然可以处理client请求。
  2. 根据KV的类型,先从内存读取数据,然后再写数据到磁盘,和之前的AOF文件无关。
    那么当子进程rewrite AOF的过程中,main thread依然可以处理新的client request。新增的数据会被放在rewrite buffer中,而且写到原有的AOF文件中。
  3. child process完成后会通知主线程。主线程有一个定时任务,也就是会不断轮询child process是否已经完成(通过信号量)。
  4. 主线程会merge 变化的数据到temp file。
  5. 主线程原子的rename到一个新的AOF文件,老AOF就不起作用了。

优点:

  1. 除了merge 和 rename需要阻塞主线程,rewrite不会阻塞主线程。(前提是使用bgrewrite command)。

最后

这些都是性能和稳定性之间做的权衡,根据不同场景需要调整。

参考

Redis latency problems troubleshooting
分布式系统原理介绍
Thoughts on Redis

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

推荐阅读更多精彩内容