core文件对问题查找非常有帮助,大部分时候我们能根据core文件直接定位到问题,但当出现内存乱掉的情况时,core的backtrace可能也不能指出问题源头。最近线上问题较多,针对dataserver出现的问题做个总结:

  1. 如果在read/write时coredump,则多是因为磁盘故障(或是文件系统崩溃),IO的一些严重问题可通过dmesg查看,如果出现Medium Error,EXT4-fs error(device sdx), Device offlined, I/O error, rejecting I/O to dead device之类的关键字,就说明磁盘已经出问题了,如果是文件系统出问题,remount一下disk应该能正常工作;
  1. 如果在读写index时coredump(每个block的索引通过mmap直接映射到内存),则多是由于访问到还没有map或是已经remap的内存,出现过的场景包括:
  • 在启动加载block的过程中,block信息已加载但index还没有映射,这时直接使用映射内存地址就会出问题;修复的方法是:访问映射内存前要检查内存是否已经映射,同时在ds加载的过程中,会拒绝客户端的访问。
  • 由于某些读取index的调用没有严格加读锁保护,导致在读与写(需要更改index的数据,可能会remap index数据)并发时,读获取到remap前的内存指针,从而在访问时coredump。当发生这种情况时,通过info threads可以查看到哪些线程在并发读写。
  1. 代码中的assert失败,也会导致coredump,但这个是可预知的,在代码中加assert,说明执行到这个地方某些数据很关键,必须确保其为某个值,否则继续执行下去可能导致不可预知的后果;比如我们认为当dataserver运行时分配不到内存,则认为系统已经出问题了,让进程直接coredump。
  1. dataserver cpu利用率持续偏高,这时需要先确定是哪些线程在占用cpu,通过top -p pid查看这个dataserver的负载情况,输入H命令显示线程的信息,可以看出哪些线程是罪魁祸首,根据线程tid与pstack的输出对照下,就能看出线程正在干什么,问题也就定位出来了,出现过的场景包括:
  • 某dataserver cpu占用率很高,切大部分花在等待IO上,通过top按内存占用排序,发现有个syslog-ng的进程(用于日志收集)占用内存达98%,同时发现swap分区也被全部使用掉了,这样就会导致dataserver的IO会被拖慢,从而cpu等待IO的时间变长。
  • 某dataserver cpu利用率高,最后定位到同步线程一直在死循环,进一步调查后发现,文件的大小在index中为0,但实际存储的长度并不为0(出现的原因较为复杂,不细说),在往辅集群同步时,同步线程一直读不到足够的文件数据而死循环,从而cpu利用率飙高。
  • 某台机器上所有dataserver重新启动,每个进程的cpu利用都很高,最后定位到是gc线程占用cpu很高,原因时,这些dataserver重新启动汇报block时,nameserver因为dataserver宕机的时间比较长,已经把这个机器上的block都复制了,导致这些ds上大部分的block是冗余的,需要被删除,删除采用延时策略,避免某些线程已经拿到了这个block删除前的指针访问导致coredump,延时删除由gc线程完成;由于磁盘是2T的,要被gc的block很多,而gc时需要读写磁盘,所以导致CPU利用率很高。

ref:
2013-04-19 14:13
blog.yunnotes.net

0 回复
需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。