本文是线上MySQL数据库问题的排查总结,希望能够对大家有所帮助。
statistics
线上服务出现大量的服务告警,怀疑是 MySQL 数据库的问题,查看监控发现有大量SQL慢查询,查询processlist,发现很多状态是 statistics。
processlist里面有好几个长时间处于 statistics 状态的线程,表示正在计算统计数据,以制定一个查询执行计划。 如果一个线程处于这种状态很长一段时间,可能是磁盘IO性能很差,或者磁盘在执行其他工作。
本文是线上MySQL数据库问题的排查总结,希望能够对大家有所帮助。
statistics
线上服务出现大量的服务告警,怀疑是 MySQL 数据库的问题,查看监控发现有大量SQL慢查询,查询processlist,发现很多状态是 statistics。
processlist里面有好几个长时间处于 statistics 状态的线程,表示正在计算统计数据,以制定一个查询执行计划。 如果一个线程处于这种状态很长一段时间,可能是磁盘IO性能很差,或者磁盘在执行其他工作。
本文给大家介绍当你的表有大量DELETE的时候,产生的表锁片如何清理,希望能够对大家有所帮助。
当我们在执行了 delete from table_name 之后会有大量的碎片空间占用,那我们应该怎么去释放呢?
如果你的 MySQL 存储引擎是 MyISAM ,那么直接执行 optimize table table_name;即可。
如果你的存储引擎是 InnoDB ,执行 optimize table table_name ,会有可能出现两行结果:
第一行:
Table does not support optimize, doing recreate + analyze instead
第二行 OK
那到底有没有成功呢?其实是成功释放了表碎片空间的。
但是有提示 Table 不支持 optimize
怎么办呢?
其实对于 InnoDB 来说,要释放表锁片空间,我们可以采用 alter table table_name ENGINE=InnoDB
。
不管是 optimize 还是 alter table 都是会锁表的,我们在操作的时候要特别注意,要选择在表变更/使用的低峰期进行操作,否则会导致大量的锁表。
解释:ALTER table table_name
其实是一个空操作,类似于重建表,可以把旧的缓存以及表的碎片空间都释放掉。
虽然 optimize table table_name
也能够释放表锁片空间,但是我们还是建议使用 ALTER TABLE table_name ENGINE=InnoDB;
本文我将带大家基于 Jaeger 构建全链路追踪系统,也包括一些我在这个过程中遇到的一些问题总结,希望能够对大家有所帮助。
分布式链路跟踪的核心基本都是 Google Dapper 论文所述,使用全局 TraceID 表示一条调用链,连接各个服务调用(用 SPAN 表示),通过分析 SPAN 之间的父子关系形成跟踪树。 另外通过中间件的埋点和业务自定义的 Annotation ,记录日志并采用收集器进行离线和在线分析,从而实现调用链跟踪、优化决策等信息。
Dapper 是 Google 发表的分布式链路跟踪的论文。
Jaeger 是 Uber 基于 Google Dapper 开发的分布式链路跟踪系统的实现。
本文是我们在分析CPU和内存开销的过程中踩过的一些坑,还有一些经验总结,希望能够对大家有所帮助。
前言
作为DevOps,我们在日常搞的项目,从开发到测试然后上线,我们基本都局限在功能的单元测试,对一些性能上的细节很多人包括我自己,往往都选择视而不见, 后果往往让工具应用产生不可预测的灾难(it’s true)。有些人说底层的东西,或者代码层面的性能调优太深入了,性能提升可以用硬件来补,但我觉得这只是自欺欺人的想法,提升硬件配置这种土豪方法不能一直长存的,更何况 现在我们的工具哪个不是分布式的,哪个不是集群上跑的,为了冗余也好,为了易于横向扩展也罢,不可能保证所有的服务器都具备高性能的,我们不能让某些低配的服务器运行我们有性能缺陷的代码产生短板,成为瓶颈。 我记得2016年参与了一些通用服务agent的开发,由于要运行于公司全网几乎所有服务器中,生产上的环境复杂程度超乎我们想象。 一个问题到达很深入的时候,就已经是共同的问题 更何况Go语言已经为开发者内置配套了很多性能调优监控的好工具和方法,这大大提升了我们profile分析的效率,除了编码技巧,不断在实战项目中磨炼自己 对性能问题分析的能力,对日后我们在项目的把控力和一些功能布局都是很有帮助。
Golang的性能调优手段
Go语言内置的CPU和Heap profiler
Go强大之处是它已经在语言层面集成了profile采样工具,并且允许我们在程序的运行时使用它们, 使用Go的profiler我们能获取以下的样本信息: * CPU profiles * Heap profiles * block profile、traces等 Go语言常见的profiling使用场景
本文是我们在使用 UDDB 的过程中的踩过的一些坑,以及一些经验总结,希望能够对大家有所帮助。
UDDB 的核心还是一个 MySQL 数据库中间件(类似 kingshard),只是产品本身是基于 UDB 的,而 UDDB 复用了 UDB 的强悍特性(安全、高可用、备份、监控、自动化运维等)。
使用很简单的,只需要按照 UDDB 的产品文档上的 SQL 指南所述,然后用 upartition 语法创建好数据库表,就可以像使用普通表一样使用 UDDB 数据库了, UDDB 的容量是可水平扩展的。
注意:我们在使用的时候是有条件的:查询时, WHERE 子句里面需要带上分区的字段信息,不然查询就是扫描全部的子表了。
UDDB 只要在初始化时创建好表之后,只需要不断扩展这个表就好了,这样的好处非常多:
比如一开始只需要存3个月的,可以只买3个节点,3个月后,等这3个节点写满,再购买3个新的节点,供后面3个月使用。而不需要一次性购买一年的节点。
本文是基于 gitfeed 项目来教你如何一步一步的用 Github+Slack+TravisCI 构建自动化持续集成。
欢迎大家使用 gitfeed 项目,有什么意见或想法都可以提 Issue 给我,更欢迎大家提 PR。
持续集成(英语:Continuous integration,缩写为 CI),一种软件工程流程,将所有工程师对于软件的工作复本,每天集成数次到共用主线(mainline)上。 摘自维基百科。
(图片来源于网络)
持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。
持续集成的好处主要有两个:
(1)快速发现错误。每完成一些更新,就可以集成到主干,可以快速发现错误,定位错误也比较容易。
(2)防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。
Martin Fowler 说过,”持续集成并不能消除 Bug,而是让它们非常容易发现和改正。”与持续集成相关的,还有两个概念,分别是持续交付和持续部署,本文暂未涉及,以后有机会再进行探讨和实践。
本文是一篇用 IFTTT 搭建属于你自己的跟踪通知系统的实战指南,希望能对你有所帮助。
占坑的帖子
本文是一篇 Jaeger 入门级指南。
以下是一篇转发
随着公司的发展,业务不断的增加,模块的不断拆分,系统间业务调用就变得越复杂,对定位线上故障带来很大困难。整个调用链不透明,犹如系统被蒙上一块黑纱,当线上遇到故障时,整个技术部就陷入痛苦的漩涡。这时候分布式追踪系统应运而生,如揭开了黑纱,让阳光照进黑暗。
opentracing是一套分布式追踪协议,与平台,语言无关,统一接口,方便开发接入不同的分布式追踪系统。
一个完整的opentracing调用链包含 Trace + span + 无限极分类
本文是一篇基于 Docker 构建 ElasticSearch 的入门级指南。
其实用 Docker 来构建真的很简单,这里就给大家贴我的实际配置和运行命令吧。
。。。
curl -XGET http://localhost:9200/_cluster/health?pretty
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "cluster_name" : "docker-cluster", "status" : "yellow", "timed_out" : false, "number_of_nodes" : 1, "number_of_data_nodes" : 1, "active_primary_shards" : 1, "active_shards" : 1, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 1, "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 50.0 } |
增加
1 2 3 4 5 6 7 |
curl -XPUT 'localhost:9200/twitter/tweet/1?pretty' -H 'Content-Type: application/json' -d' { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" } ' |
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "_index" : "twitter", "_type" : "tweet", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 1 } |
查询
curl -XGET 'http://localhost:9200/twitter/tweet/1'
执行结果:
1 2 3 4 5 6 7 |
{"_index":"twitter","_type":"tweet","_id":"1","_version":1,"found":true,"_source": { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" } } |
https://github.com/olivere/elastic/issues/312 https://github.com/olivere/elastic/wiki/Connection-Problems#how-to-figure-out-connection-problems