微信 日志服务器 并发大,微信高性能线上日志系统xlog剖析

微信高性能线上日志系统xlog剖析

做移动开发的同学经常会遇到一个头疼的问题,就是当用户反馈一些问题,又比较冷僻难以复现的时候(不是Crash),常常就会陷入一筹莫展的境地。因此,很多人就研发了相关的监控系统,比如一些知名的APM来监测帧率、内存、电量等等,将这些数据进行采集、合并再上报至专门的平台供开发测试同学查看。但是这些APM往往都是粗粒度的监控,究其原因就在于如果特别精细的进行监控,线上的性能会吃不消,一些监控反而影响了用户的正常使用。

说了这么多,抛开获取数据方面的难度不提,线上监控的本质还是在于信息(日志)记录,而端上的日志记录存在一个社会主义初级阶段的供需矛盾:

即实时细粒度的日志记录的性能落差和日志的完整不丢失无法兼顾。

如果你要高性能、细粒度的记录日志,那你势必大量使用内存。而大量使用使用内存,万一没电了、程序突然崩了,这些中间态的日志还没持久化,就相当于白费了精力;而如果你想保证可靠性,那你就需要经常实时落盘。我们知道,写磁盘的行为是会设计用户态和内核态的切换,在高流畅性的要求下是绝对会影响性能了,而且这还不是你开多线程能够解决的问题。

写磁盘为什么会非常慢

现如今、几乎所有的操作系统在管理内存的时候,基本采用了页式管理的策略。即将连续的内存空间(注意空间,不是地址)换成了一个个页式大小。这样的好处有几点:

按页这种大小进行管理、可以有效的减少内存碎片的粒度。

按页加载,可以充分利用磁盘上的交换空间,使得程序使用的空间能大大超过内存限制。

当然,iOS设备上不存在交换空间,但是也依然按照页式结构进行内存管理。

回到为什么写磁盘会慢的问题上。我们一般会把内存中的数据进行持久化储存到磁盘上。但是写入磁盘并不是你想写就立刻写的,数据是通过flush的方式从内存写回到磁盘,一般有如下几种情况:

通过页的flag标记为有改动,操作系统定时将这种脏页写回到磁盘上,时机不可控。

调用用户态的写接口->触发内核态的sys_write->文件系统将数据写回磁盘。

乍一看上述第二种方式非常适合写日志,但是其包含两个非常明显的问题:

文件系统处于效率不会立刻将数据写回到磁盘(比如磁道寻址由于机械操作的原因相对非常耗时),而是以Block块的形式缓存在队列中,经过排序、合并到达一定比例之后再写回磁盘。

这种方式在将数据写回到磁盘时,需要经历两次拷贝。一次是把数据从用户态拷贝到内核态,需要经历上下文切换;还有一次是内核空间到硬盘上真正的数据拷贝。当切换次数过于频繁,整体性能也会下降。

基于上述这些问题,xlog采用了mmap的方案进行日志系统的设计:

mmap 是使用逻辑内存对磁盘文件进行映射,中间只是进行映射没有任何拷贝操作,避免了写文件的数据拷贝。操作内存就相当于在操作文件,避免了内核空间和用户空间的频繁切换。

除了系能耐,使用mmap还能保证日志的完整性,因为如下这些情况下回自动回写磁盘:

内存不足

进程 crash

调用 msync 或者 munmap

不设置 MAP_NOSYNC 情况下 30s-60s(仅限FreeBSD)

xlog源码分析

xlog的代码主要分为两块,面向上层的使用封装xlogger,暴露了一系列的借口。以及核心的appender和log等。

log_buffer

log_buffer其目的是封装了一个对mma

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值