抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

搞不定数据收敛和提效建设,就别扯数据治理了

作者介绍

李清华,贝壳 资深产品经理。武汉大学毕业,在百度、蚂蚁金服、贝壳先后从事数据治理和数据安全相关工作,现在是贝壳找房业务数据中心的产品负责人,核心在对业务数据进行治理,提升中台模式下组织间的协作效率。

 

数据治理经过多年的沉淀,积累了比较完善的理论体系;但是落地时候,治理范围如何聚焦,数据产品如何定位、具象设计和推广运营,不同公司有着不同的设计实现。本文会结合贝壳找房近两年的业务数据中心建设经验,从产品视角来谈谈数据治理的问题。主要内容包括:

 

  • 数据治理目的及内容

 

  • 结合公司特点聚焦治理范围

 

  • 中台侧实践的建设内容及思路

 

  • 治理项目的目标管理

 

  • 产品及运营落地经验

 

一、数据治理目的及内容

 

 
1、贝壳找房介绍

 

图片

 

贝壳的主要C端产品是贝壳找房app,围绕居住领域,提供二手、新房、租赁、装修等品质服务。

 

 
2、数据治理目的

 

图片

 

数据治理的终极目的,是提升数据的使用价值。数据是公司的重要资产。数据使用包括两方面:一是通过数据为用户提供更好的服务,如推荐算法;另一方面是利用数据,来为管理提供抓手,更高效地管控业务,在这种情况下,功能创新和管理提效,都依赖于数据被更好地利用,这也是数据治理要解决的核心问题。以下是提升数据使用价值的三个方向。

 

1) 共享

 

共享性的提升,是指让公司内部所有的要用到数据的同学,知道公司有哪些数据,找人找数更加便捷。

 

首先从业务视角来看,在日常的需求对接中,通常会通过邮件、PRD、共享文档等载体来管理和记录数据,一旦发生人员调转,或者业务组织架构调整,数据的背景前提就无法考证。很多情况下,数据逻辑只有相关产研了解,需要较高的沟通成本。另一方面,从公司视角去看共享性这个问题,公司的业务系统众多,导致数据分散在各个部门管理,无法流通起来。在这种情况下,我们需要一系统平台,对数据做统一的收口,使得高流通的数据可见、可查、可申请、可管理。

 

2)准确

 

第二个方向是基于准确性的考量。

 

在现实场景中,一个业务字段可能需要从多个维度去定义和描述,包括业务含义,图文解释说明等。但是数据提供方的记录文档,常常不够清晰和完整。我们希望,业务方通过系统平台看到相关数据后,可以判断出它的业务含义,以及是否符合诉求,是否可用。数据治理想做的事,就包括通过工具约束,对字段进行维护和补全。

 

业务自身在迭代过程中,会产成多个版本;数据业务含义的历史变更等,都需要进行维护。

 

不管是实时的业务系统数据还是接口数据,我们希望提高搜索的准确性,降低沟通成本。

 

业务迭代过程中,上游发生变化时,需要及时触达到下游的关注方,这也是我们系统要解决的问题。

 

3)可用

 

可用性主要是指做到让数据可信赖。已经下线的数据,如果文档没有同步下线,可能造成下游使用方继续调用数据,影响业务;此外,对数据健康状态的监控预警,如事件类消息的消费积压等,也需要及时触达下游;然后,通过元数据的血缘关系,可以帮助业务方更快查找问题;最后,为降低下游消费方解析数据的成本,应该尽量保证流通性数据的数据格式统一。

 

 
3、数据治理范围

 

图片

 

对于大量的用户数据,我们会对相应的埋点数据进行管理;加工用户数据的数仓表,需要进行元数据和数据血缘的管理;加工得到的指标,需要解决的问题包括指标合理化定义,指标认证,指标高效检索等。

 

除了上面介绍的离线数据,还有一些业务主体数据,如贝壳经纪人相关的作业数据等业务系统实时数据,会落到mysql表中,或是加工成流通的数据形式:如以kafka消息,或实时接口的形式提供。完善的数据治理需要多年的时间,公司可结合自身业务特点和系统交互模式,针对现阶段问题对症下药进行治理,把小类问题做好,即可发挥数据治理的价值。

 

二、结合公司特点聚焦治理范围

 

下面介绍,我们在以往的经验中,是如何结合公司业务的需求,确定数据治理的范围的。

 

 
1、系统特点

 

图片

 

主要从两个方面来看贝壳对数据治理的要求。

 

首先,贝壳业务数据系统特点,更偏中台属性,许多前台应用无法实现数据的自给自足,需要依赖中台进行数据传输,如C端界面呈现的大多数信息等。同时,一些精细化的运营动作,风控、品质相关的智能算法,实时金额奖励等都需要用到中台侧的实时数据,这部分需求的特点是高频且强依赖。

 

另一个视角看,中台侧自身也存在一些同质化问题,比如数据本身的黑盒化:数据都收口在中台,没有向用户普及,就会影响数据的共享,造成沟通成本较高。另外,一些需求的开发成本较高,需要较多产品、研发、测试同学参与,需要进行提效。第三点是存在格式混乱、可读性较差的问题,这些问题会导致中台侧对一些紧急的数据需求无法及时响应。

 

基于以上问题,需要业务中心来对中心化的数据做统一的治理、收口和质量管控。主要包括两个核心:数据收敛和提效建设。数据收敛主要解决数据不共享的问题,把一些高流通的接口和事件类数据做集中的发布,并做相应的质量管控。提效建设是为了让更少的人力参与到高频且复杂的数据流通过程中,把产研人力释放出来,投入到对公司价值更高的业务开发和业务迭代中。

 

 
2、业务特点

 

以上是从公司业务系统交互模式上考虑,需要建设数据治理中心。下面从公司本身的业务特点来分析。

 

图片

 

许多为传统行业赋能的互联网公司都有作业的主体,如贝壳找房的经纪人等,这就导致很多业务运营诉求的产生:需要利用数据,对业务进行正向牵引,对作业人员进行管控。比如对经纪人上传房源的备件信息来保证房源质量等正向行为的激励,对一些作弊行为的处罚等。这类需求的特点是对数据的实时性要求非常高,奖励要及时发放,关黑等处罚要及时处理。而上述这些正向牵引和管控,依赖对实时数据源的监听,要求数据中心本身要收口足够丰富的数据。

 

以“共享”和“业务语义可读”举例来说,业务运营的同学需要配置一些运营规则时,能够通过数据源,快速判断如何使用数据,来辅助运营策略。

 

许多公司都会遇到运营规则演变一段时间后,策略规则需要优化和提升。这就需要数据准确且可回溯,能够找回依赖的数据源,完成策略优化工作。

 

结合贝壳的业务特点,我们的业务数据中心主要对业务主体关联的明细信息接口,和业务节点的kafka消息做重点治理。

 

以上从系统特点和公司业务特点,介绍了数据治理的背景环境。下面展开介绍数据收敛和提效建设的必要性。

 

 
3、数据收敛必要性

 

图片

 

首先,由于中台维护的数据不够全面,有大量的高成本单次取数需求,需要业务方来支持,且这些数据往往缺少文档记录,完成需求需要较高的沟通成本。这类需求量级大,频率高,管理者可能会采用增加人力的方式来解决。造成人力成本较高。

 

公司在做数据赋能过程中,包括AI、品质风控、精细化运营等团队,需要来自不同业务方的大批量数据,取数效率低会成为卡点,影响核心项目的展开。所以有必要通过业务中台对数据进行治理。

 

 
4、提效建设必要性

 

图片

 

提效建设方面,如果通过管理层从上向下推动,往往不够高效。建议结合数据流通中产研的痛点问题,将提效做到平台产品中,释放人力,这样执行层就会更通畅地接入。

 

三、中台侧实践的建设内容及思路

 

 
1、建设内容

 

图片

 

提效建设围绕从生产到发布测试的整个流程,包括自助测试、查询订阅等功能,方便整个公司更高效地访问数据。数据从生产、测试、查询使用、权限申请的闭环都通过平台来管控。

 

 
2、产品框架

 

图片

 

在产品架构上,根据治理的数据主体分为不同类,如接口、事件、指标、数据表等。每个类下面有多个领域模块。比如生产环节提效方面,支持配置化开发;发布时统一格式规范和查询入口;支持用户根据需求,自主订阅查询;测试时支持自助联调测试;以及通过监控和预警模块,对数据质量进行管控等。

 

 
3、建设思路

 

图片

 

建设思路首先要建能力。我们有很多的数据生产方,所以针对生产环节进行了一系列功能性建设,支持数据更便捷的加工、发布、关联业务属性,以及从生产者视角查看下游链路、订阅方,数据变更的触达等。

 

平台对消费方的支持,包括支持统一的查询、自助订阅、对已授权数据的管理、变更触达等。生产和消费功能具备后,就可以启动推广。推广过程中的问题怎么解决,后面会有具体的例子来说明。

 

当数据都收敛到平台上之后,才知道有哪些数据可以治理。首先要识别有哪些问题数据;另外要完善数据认证的功能,来提高取数的便捷性;在质量维护方面,通过线上的反馈和触达机制,结合问题报告等管理方法,来代替运营走查的方式,形成良性循环。

 

数据治理工作依赖很多组织的配合。比如公司通常有治理委员会,还需要跟安全、法务部门有协作,以及会有一些自上而下的数据规范标准等,这些组织依赖会影响数据治理的设计。能力依赖方面,数据有非常多的应用,以数据请求为例,就需要基础且统一的服务标识;还可以通过链路日志的分析,来辅助识别问题;鉴权方面也需要相应的能力等。

 

四、治理项目的目标管理

 

图片

 

目标管理第一是能找到数据。许多核心业务项目的数据,都通过平台来获取,可以通过平台对业务数据需求的满足率来评价。第二要求在业务方使用数据过程中,数据清晰可理解,量化为核心指标字段信息的完备率、以及平台中心化认证数据的占比。第三要提高数据使用中的质量,减少badcase数量,这方面可以和公司的工作流系统、故障组等配合,来量化这个指标。

 

五、产品及运营落地经验

 

图片

 

以下是一些想要共享的建议。治理团队最好不要做只负责建设工具的独立团队,在设计之初,承接一段时间业务需求,才会了解业务方真实的诉求。“治理团队要长在业务的土壤中”。在需求场景中发现的问题,是只通过调研访谈用户无法发现的。我们在做治理中心的时候,会承接业务方的数据需求。通过对整个流程中,产品、研发、测试的具体工作有比较深刻的体验,才能设计好产品。

 

 
1、数据收敛经验——目标用户触达

 

图片

 

产品设计完成后,一般结合几个试点用户的反馈来建设能力。之后就需要进行推广。首先要明确平台服务的用户,如果用户是整个公司的产研,可以利用公司内的电子屏、海报机等展位,以及公司的内网来对用户进行触达。

 

 
2、数据收敛经验——深度需求挖掘

 

图片

 

即便进行了大量的宣传和推广,可能收效仍然有限。这种情况下,可以到各个业务线进行深度访谈和宣讲,使得产品功能与用户诉求相匹配。通过宣讲,也可以发现一些产品还欠缺的关键的能力点,帮助我们完善产品建设。此外,可以通过集思广益,广泛收集反馈,以及与行业内同类产品对标,通过需求驱动产品的进一步规划。

 

 
3、数据收敛经验——良性牵引

 

图片

 

除了前期的推广,产品更重要的是要通过核心的价值点,来吸引目标用户。以下是结合贝壳自身特点的举例,并不一定适用于所有业务线。我们做的比较好的一点是对数据格式进行来收敛。因为格式不统一是数据使用方很大的痛点,平台实现了这个功能,使用方就会驱动生产方将数据生产迁移到平台上。推动格式统一的过程中,如果生产高流通数据的业务方不愿意遵守格式规范,中台会通过产研支持的方式,帮助完成中间层的开发和转化。

 

图片

 

另外一点比较好的经验是与公司核心数据获取方建立合作机制,让相关系统的规则引擎、运营产品等,使用业务数据中心平台的数据,借此驱动更多数据的生产方将数据发布到业务数据中心,使得平台的数据源更加丰富和全面。建设初期,中心主动跟进一些数据需求,并将需求发布到平台上,由数据中心平台来做统一的收敛和治理,沉淀出新的功能点、管理手段、规则标准等,来推动工具建设。平台能力建设好之后,再通过自上而下的推动,平台产品的价值会得到越来越多的接受和认可。

 

 
4、治理难点及举措

 

图片

 

最后介绍一下我们遇到的一些问题,以及解决这些问题的举措。

 

首先,数据治理涉及生产提效、数据统一、标准收口、数据共享、内容治理、质量、稳定性等很多方面,需要公司给予战略层级的支持,需要相关的架构负责人共同讨论和设计,自上而下去推动。

 

产品设计方面,要结合公司自己的业务形态去摸索、迭代和沉淀。这个过程中,首先要尊重用户,不能只调研少量业务方后,就设计产品功能。而应制定标准,做好迭代。最初可以从文档管理开始,逐步进行系统化收口。此外还要大胆创新。一些产品功能,比如业务词典,依赖对业务的深刻理解。业务本身产生的数据,如核心SOP流程、名词解释、测试链接、账号等,都需要系统化梳理,才能保障更好地使用数据。
 
此外我们也会做一些前沿的探索,感兴趣的同学可以一起交流。

 

能力依赖方面,需要和公司的基础设施、业务系统都有好的联动,所以合作共赢的意识非常重要。

 

推广运营需要擅长借力,一方面通过自上而下的驱动,另一方面产品要有核心的竞争力。此外,推动数据收口和治理,流通管控过程中,可以与安全、法务团队紧密合作,一起推动。

 

>>>>

Q&A

 

Q1:数据收敛与数据治理的区别
A1:这里所说的数据收敛,是指把管控的高流通数据都统一收口到平台。数据治理首先要让数据透明化,将猎物关在篮子里,才能对质量进行管控。
 
Q2:如何解决不同业务之间模糊地带的权责划分?
A2:中台工具搭建之后,数据治理更多是依赖工具的使用者来推动。
 
Q3:中台部门是成本部门,在贝壳的实践中,中台提升数据价值是如何体现的?如何让中台部门的同学有好的收益,对团队更有信心?
A3:举个例子,比如业务新增加一个上报的动作,如果业务方自己开发,功能开发之后需要等待测试同学排期,以及后续一系列上线流程都比较耗时。但是如果是中台来做,我们会监控原始数据的变动,然后根据业务事件定义的规则,对新增加的事件进行定义和自助测试。这个过程不需要测试同学介入即可完成上线发布。如果后续有同学需要用这些新增加的数据进行联调,我们可以提供测试样例,并把这部分数据发到对方的kafka topic里。

 

作者丨李清华
来源丨公众号:DataFunTalk(ID:datafuntalk)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

系统、应用监控的缜密思路,堪称性能瓶颈的克星

一、起始

 

在实际的性能分析中,一个很常见的现象是,明明发生了性能瓶颈,但当你登录到服务器中想要排查的时候,却发现瓶颈已经消失了。或者说,性能问题总是时不时地发生,但却很难找出发生规律,也很难重现。

 

而要解决这个问题,就要搭建监控系统,把系统和应用程序的运行状况监控起来,并定义一系列的策略,在发生问题时第一时间告警通知。一个好的监控系统,不仅可以实时暴露系统的各种问题,更可以根据这些监控到的状态,自动分析和定位大致的瓶颈来源,从而更精确地把问题汇报给相关团队处理。要做好监控,最核心的就是全面的、可量化的指标,这包括系统和应用两个方面。

 

从系统来说,监控系统要涵盖系统的整体资源使用情况,比如我们前面讲过的 CPU、内存、磁盘和文件系统、网络等各种系统资源。

 

而从应用程序来说,监控系统要涵盖应用程序内部的运行状态,这既包括进程的 CPU、磁盘 I/O 等整体运行状况,更需要包括诸如接口调用耗时、执行过程中的错误、内部对象的内存使用等应用程序内部的运行状况。

 

二、系统监控

 

 
1、USE 法

 

在开始监控系统之前,你肯定最想知道,怎么才能用简洁的方法,来描述系统资源的使用情况。你当然可以使用专栏中学到的各种性能工具,来分别收集各种资源的使用情况。不过不要忘记,每种资源的性能指标可都有很多,使用过多指标本身耗时耗力不说,也不容易为你建立起系统整体的运行状况。

 

在这里,我为你介绍一种专门用于性能监控的 USE(Utilization Saturation and Errors)法。

 

USE 法把系统资源的性能指标,简化成了三个类别,即使用率、饱和度以及错误数。

 

使用率,表示资源用于服务的时间或容量百分比。100% 的使用率,表示容量已经用尽或者全部时间都用于服务。

 

饱和度,表示资源的繁忙程度,通常与等待队列的长度相关。100% 的饱和度,表示资源无法接受更多的请求。

 

错误数表示发生错误的事件个数。错误数越多,表明系统的问题越严重。

 

这三个类别的指标,涵盖了系统资源的常见性能瓶颈,所以常被用来快速定位系统资源的性能瓶颈。这样,无论是对 CPU、内存、磁盘和文件系统、网络等硬件资源,还是对文件描述符数、连接数、连接跟踪数等软件资源,USE 方法都可以帮你快速定位出,是哪一种系统资源出现了性能瓶颈。

 

 
2、性能指标

 

那么,对于每一种系统资源,又有哪些常见的性能指标呢?回忆一下我们讲过的各种系统资源原理,并不难想到相关的性能指标。这里,我把常见的性能指标画了一张表格,方便你在需要时查看。

 

图片

 

不过,需要注意的是,USE 方法只关注能体现系统资源性能瓶颈的核心指标,但这并不是说其他指标不重要。诸如系统日志、进程资源使用量、缓存使用量等其他各类指标,也都需要我们监控起来。只不过,它们通常用作辅助性能分析,而 USE 方法的指标,则直接表明了系统的资源瓶颈。

 

 
3、监控系统

 

掌握 USE 方法以及需要监控的性能指标后,接下来要做的,就是建立监控系统,把这些指标保存下来;然后,根据这些监控到的状态,自动分析和定位大致的瓶颈来源;最后,再通过告警系统,把问题及时汇报给相关团队处理。

 

可以看出,一个完整的监控系统通常由数据采集、数据存储、数据查询和处理、告警以及可视化展示等多个模块组成。所以,要从头搭建一个监控系统,其实也是一个很大的系统工程。

 

不过,幸运的是,现在已经有很多开源的监控工具可以直接使用,比如最常见的 Zabbix、Nagios、Prometheus 等等。

 

下面,我就以 Prometheus 为例,为你介绍这几个组件的基本原理。如下图所示,就是 Prometheus 的基本架构:

 

图片

(图片来自 prometheus.io)

 

先看数据采集模块。最左边的 Prometheus targets 就是数据采集的对象,而 Retrieval 则负责采集这些数据。从图中你也可以看到,Prometheus 同时支持 Push 和 Pull 两种数据采集模式。

 

Pull 模式,由服务器端的采集模块来触发采集。只要采集目标提供了 HTTP 接口,就可以自由接入(这也是最常用的采集模式)。

 

Push 模式,则是由各个采集目标主动向 Push Gateway(用于防止数据丢失)推送指标,再由服务器端从 Gateway 中拉取过去(这是移动应用中最常用的采集模式)。

第二个是数据存储模块。为了保持监控数据的持久化,图中的 TSDB(Time series database)模块,负责将采集到的数据持久化到 SSD 等磁盘设备中。TSDB 是专门为时间序列数据设计的一种数据库,特点是以时间为索引、数据量大并且以追加的方式写入。

 

第三个是数据查询和处理模块。刚才提到的 TSDB,在存储数据的同时,其实还提供了数据查询和基本的数据处理功能,而这也就是 PromQL 语言。PromQL 提供了简洁的查询、过滤功能,并且支持基本的数据处理方法,是告警系统和可视化展示的基础。

 

第四个是告警模块。右上角的 AlertManager 提供了告警的功能,包括基于 PromQL 语言的触发条件、告警规则的配置管理以及告警的发送等。不过,虽然告警是必要的,但过于频繁的告警显然也不可取。所以,AlertManager 还支持通过分组、抑制或者静默等多种方式来聚合同类告警,并减少告警数量。

 

最后一个是可视化展示模块。Prometheus 的 web UI 提供了简单的可视化界面,用于执行 PromQL 查询语句,但结果的展示比较单调。不过,一旦配合 Grafana,就可以构建非常强大的图形界面了。介绍完了这些组件,想必你对每个模块都有了比较清晰的认识。接下来,我们再来继续深入了解这些组件结合起来的整体功能。比如,以刚才提到的 USE 方法为例,我使用 Prometheus,可以收集 Linux 服务器的 CPU、内存、磁盘、网络等各类资源的使用率、饱和度和错误数指标。然后,通过 Grafana 以及 PromQL 查询语句,就可以把它们以图形界面的方式直观展示出来。

 

图片

 

 
4、最后总结

 

系统监控的核心是资源的使用情况,这既包括 CPU、内存、磁盘、文件系统、网络等硬件资源,也包括文件描述符数、连接数、连接跟踪数等软件资源。而要描述这些资源瓶颈,最简单有效的方法就是 USE 法。

 

USE 法把系统资源的性能指标,简化为了三个类别:使用率、饱和度以及错误数。当这三者之中任一类别的指标过高时,都代表相对应的系统资源可能存在性能瓶颈。

 

基于 USE 法建立性能指标后,我们还需要通过一套完整的监控系统,把这些指标从采集、存储、查询、处理,再到告警和可视化展示等贯穿起来。这样,不仅可以将系统资源的瓶颈快速暴露出来,还可以借助监控的历史数据,来追踪定位性能问题的根源。

 

三、应用监控

 

 
1、应用监控指标

 

跟系统监控一样,在构建应用程序的监控系统之前,首先也需要确定,到底需要监控哪些指标。特别是要清楚,有哪些指标可以用来快速确认应用程序的性能问题。

 

应用程序的核心指标,不再是资源的使用情况,而是请求数、错误率和响应时间。

 

这些指标不仅直接关系到用户的使用体验,还反映应用整体的可用性和可靠性。有了请求数、错误率和响应时间这三个黄金指标之后,我们就可以快速知道,应用是否发生了性能问题。但是,只有这些指标显然还是不够的,因为发生性能问题后,我们还希望能够快速定位“性能瓶颈区”。所以,在我看来,下面几种指标,也是监控应用程序时必不可少的。

 

第一个,是应用进程的资源使用情况,比如进程占用的 CPU、内存、磁盘 I/O、网络等。使用过多的系统资源,导致应用程序响应缓慢或者错误数升高,是一个最常见的性能问题。

 

第二个,是应用程序之间调用情况,比如调用频率、错误数、延时等。由于应用程序并不是孤立的,如果其依赖的其他应用出现了性能问题,应用自身性能也会受到影响。

 

第三个,是应用程序内部核心逻辑的运行情况,比如关键环节的耗时以及执行过程中的错误等。由于这是应用程序内部的状态,从外部通常无法直接获取到详细的性能数据。所以,应用程序在设计和开发时,就应该把这些指标提供出来,以便监控系统可以了解其内部运行状态。

 

有了应用进程的资源使用指标,你就可以把系统资源的瓶颈跟应用程序关联起来,从而迅速定位因系统资源不足而导致的性能问题;

 

有了应用程序之间的调用指标,你可以迅速分析出一个请求处理的调用链中,到底哪个组件才是导致性能问题的罪魁祸首;

 

而有了应用程序内部核心逻辑的运行性能,你就可以更进一步,直接进入应用程序的内部,定位到底是哪个处理环节的函数导致了性能问题。

 

基于这些思路,我相信你就可以构建出,描述应用程序运行状态的性能指标。再将这些指标纳入我们上一期提到的监控系统(比如 Prometheus + Grafana)中,就可以跟系统监控一样,一方面通过告警系统,把问题及时汇报给相关团队处理;另一方面,通过直观的图形界面,动态展示应用程序的整体性能。

 

 
2、全链路监控

 

业务系统通常会涉及到一连串的多个服务,形成一个复杂的分布式调用链。为了迅速定位这类跨应用的性能瓶颈,你还可以使用 Zipkin、Jaeger、Pinpoint 等各类开源工具,来构建全链路跟踪系统。比如,下图就是一个 Jaeger 调用链跟踪的示例。

 

图片

(图片来自 Jaeger 文档)

 

全链路跟踪可以帮你迅速定位出,在一个请求处理过程中,哪个环节才是问题根源。比如,从上图中,你就可以很容易看到,这是 Redis 超时导致的问题。

 

全链路跟踪除了可以帮你快速定位跨应用的性能问题外,还可以帮你生成线上系统的调用拓扑图。这些直观的拓扑图,在分析复杂系统(比如微服务)时尤其有效。

 

 
3、日志监控

 

性能指标的监控,可以让你迅速定位发生瓶颈的位置,不过只有指标的话往往还不够。比如,同样的一个接口,当请求传入的参数不同时,就可能会导致完全不同的性能问题。所以,除了指标外,我们还需要对这些指标的上下文信息进行监控,而日志正是这些上下文的最佳来源。

 

对比来看,指标是特定时间段的数值型测量数据,通常以时间序列的方式处理,适合于实时监控。

 

而日志则完全不同,日志都是某个时间点的字符串消息,通常需要对搜索引擎进行索引后,才能进行查询和汇总分析。

 

对日志监控来说,最经典的方法,就是使用 ELK 技术栈,即使用 Elasticsearch、Logstash 和 Kibana 这三个组件的组合。

 

如下图所示,就是一个经典的 ELK 架构图:

 

图片

(图片来自elastic.co)

 

Logstash 负责对从各个日志源采集日志,然后进行预处理,最后再把初步处理过的日志,发送给 Elasticsearch 进行索引。

 

Elasticsearch 负责对日志进行索引,并提供了一个完整的全文搜索引擎,这样就可以方便你从日志中检索需要的数据。

 

Kibana 则负责对日志进行可视化分析,包括日志搜索、处理以及绚丽的仪表板展示等。

 

下面这张图,就是一个 Kibana 仪表板的示例,它直观展示了 Apache 的访问概况。

 

图片

(图片来自elastic.co)

 

值得注意的是,ELK 技术栈中的 Logstash 资源消耗比较大。所以,在资源紧张的环境中,我们往往使用资源消耗更低的 Fluentd,来替代 Logstash(也就是所谓的 EFK 技术栈)。

 

 
4、最后总结

 

应用程序的监控,可以分为指标监控和日志监控两大部分:

 

指标监控主要是对一定时间段内性能指标进行测量,然后再通过时间序列的方式,进行处理、存储和告警。

 

日志监控则可以提供更详细的上下文信息,通常通过 ELK 技术栈来进行收集、索引和图形化展示。

 

在跨多个不同应用的复杂业务场景中,你还可以构建全链路跟踪系统。这样可以动态跟踪调用链中各个组件的性能,生成整个流程的调用拓扑图,从而加快定位复杂应用的性能问题。

 

作者丨-零

来源丨网址:

www.cnblogs.com/-wenli/p/14017850.html

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

重现MySQL索引失效10个场景,都帮你把坑挖好了

前言

 

之前在《15 种 SQL 优化中,老司机才懂的处理技巧》这篇文章中,从15个方面分享了SQL优化的一些小技巧。今天接着上一期数据库的话题,更进一步聊聊索引的相关问题,因为索引是大家都比较关心的公共话题,确实有很多坑。

 

不知道你在实际工作中,有没有遇到过下面的这两种情况:

 

  • 明明在某个字段上加了索引,但实际上并没有生效。

  • 索引有时候生效了,有时候没有生效。

 

今天就跟大家一起聊聊,MySQL数据库索引失效的10种场景,给曾经踩过坑,或者即将要踩坑的朋友们一个参考。

 

图片

 

一、准备工作

 

所谓空口无凭,如果我直接把索引失效的这些场景丢出来,可能没有任何说服力。

 

所以,我决定建表和造数据,给大家一步步演示效果,尽量做到有理有据。

 

我相信,如果大家耐心的看完这篇文章,一定会有很多收获的。

 

 
1、创建user表

 

创建一张user表,表中包含:id、code、age、name和height字段。

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
CREATE TABLE `user` (  `id` int NOT NULL AUTO_INCREMENT,  `code` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,  `age` int DEFAULT '0',  `name` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,  `height` int DEFAULT '0',  `address` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `idx_code_age_name` (`code`,`age`,`name`),  KEY `idx_height` (`height`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

 

此外,还创建了三个索引:

 

  • id:数据库的主键

  • idx_code_age_name:由code、age和name三个字段组成的联合索引。

  • idx_height:普通索引

 

 
2、插入数据

 

为了方便给大家做演示,我特意向user表中插入了3条数据:

 

  •  
  •  
  •  
INSERT INTO sue.user (id, code, age, name, height) VALUES (1, '101', 21, '周星驰', 175,'香港');INSERT INTO sue.user (id, code, age, name, height) VALUES (2, '102', 18, '周杰伦', 173,'台湾');INSERT INTO sue.user (id, code, age, name, height) VALUES (3, '103', 23, '苏三', 174,'成都');

 

周星驰和周杰伦是我偶像,在这里自恋了一次,把他们和我放到一起了。哈哈哈。

 

 
3、查看数据库版本

 

为了防止以后出现不必要的误会,在这里有必要查一下当前数据库的版本。不说版本就直接给结论,是耍流氓,哈哈哈。

 

  •  
select version();

 

查出当前的MySQL版本号为:8.0.21

 

 
4、查看执行计划

 

在MySQL中,如果你想查看某条SQL语句是否使用了索引,或者已建好的索引是否失效,可以通过explain关键字,查看该SQL语句的执行计划,来判断索引使用情况。

 

例如:

 

  •  
explain select * from user where id=1;

 

执行结果:

 

图片

 

从图中可以看出,由于id字段是主键,该SQL语句用到了主键索引

 

当然,如果你想更深入的了解explain关键字的用法,可以看看我的另一篇文章《explain 索引优化的这把绝世好剑,你真的会用吗?》,里面更为详细的介绍。

 

二、不满足最左匹配原则

 

之前我已经给code、age和name这3个字段建好联合索引:idx_code_age_name。

 

该索引字段的顺序是:

 

  • code

  • age

  • name

 

如果在使用联合索引时,没注意最左前缀原则,很有可能导致索引失效喔,不信我们一起往下看。

 

 
1、哪些情况索引有效?

 

先看看哪些情况下,能走索引。

 

  •  
  •  
explain select * from userwhere code='101';

 

  •  
  •  
explain select * from userwhere code='101' and age=21 

 

  •  
  •  
explain select * from userwhere code='101' and age=21 and name='周星驰';

 

执行结果:

 

图片

 

上面三种情况,SQL都能正常走索引。

 

其实还有一种比较特殊的场景:

 

  •  
  •  
explain select * from userwhere code = '101'  and name='周星驰';

 

执行结果:

 

图片

 

查询条件原本的顺序是:code、age、name,但这里只有code和name中间断层了,掉了age字段,这种情况也能走code字段上的索引。

 

看到这里,不知道聪明的你,有没有发现这样一个规律:这4条SQL中都有code字段,它是索引字段中的第一个字段,也就是最左边的字段。只要有这个字段在,该SQL已经就能走索引。

 

这就是我们所说的最左匹配原则。

 

 
2、哪些情况索引失效?

 

前面我已经介绍过,建立了联合索引后,在查询条件中有哪些情况索引是有效的。

 

接下来,我们重点看看哪些情况下索引会失效。

 

  •  
  •  
explain select * from userwhere age=21;

 

  •  
  •  
explain select * from userwhere name='周星驰';

 

  •  
  •  
explain select * from userwhere age=21 and name='周星驰';

 

执行结果:

 

图片

 

从图中看出这3种情况下索引确实失效了。

 

说明以上3种情况不满足最左匹配原则,说白了是因为查询条件中,没有包含给定字段最左边的索引字段,即字段code。

 

三、使用了select *

 

在《阿里巴巴开发手册》中明确说过,查询SQL中禁止使用select * 。

 

那么,你知道为什么吗?

 

废话不多说,按照国际惯例先上一条SQL

 

  •  
  •  
explain select * from user where name='苏三';

 

执行结果:

 

图片

 

在该SQL中用了select *,从执行结果看,走了全表扫描,没有用到任何索引,查询效率是非常低的。

 

如果查询的时候,只查我们真正需要的列,而不查所有列,结果会怎么样?

 

非常快速的将上面的SQL改成只查了code和name列,太easy了:

 

  •  
  •  
  •  
explain select code,name from user where name='苏三';

 

执行结果:

 

图片

 

从图中执行结果不难看出,该SQL语句这次走了全索引扫描,比全表扫描效率更高。

 

其实这里用到了:覆盖索引。

 

如果select语句中的查询列,都是索引列,那么这些列被称为覆盖索引。这种情况下,查询的相关字段都能走索引,索引查询效率相对来说更高一些。

 

而使用select *查询所有列的数据,大概率会查询非索引列的数据,非索引列不会走索引,查询效率非常低。

 

四、索引列上有计算

 

介绍本章节内容前,先跟大家一起回顾一下,根据id查询数据的SQL语句:

 

  •  
explain select * from user where id=1;

 

执行结果:

 

图片

 

从图中可以看出,由于id字段是主键,该SQL语句用到了主键索引。

 

但如果id列上面有计算,比如:

 

  •  
explain select * from user where id+1=2;

 

执行结果:

 

图片

 

从上图中的执行结果,能够非常清楚的看出,该id字段的主键索引,在有计算的情况下失效了。

 

五、索引列用了函数

 

有时候我们在某条SQL语句的查询条件中,需要使用函数,比如:截取某个字段的长度。

 

假如现在有个需求:想查出所有身高是17开头的人,如果SQL句写成这样:

 

  •  
explain select * from user  where height=17;

 

SQL语句确实用到了普通索引:

 

图片

 

但该SQL语句肯定是有问题的,因为它只能查出身高正好等于17的,但对于174这种情况,它没办法查出来。

 

为了满足上面的要求,我们需要把SQL语句稍稍改造了一下:

 

  •  
explain select * from user  where SUBSTR(height,1,2)=17;

 

这时需要用到SUBSTR函数,用它截取了height字段的前面两位字符,从第一个字符开始。

 

执行结果:

 

图片

 

你有没有发现,在使用该函数之后,该SQL语句竟然走了全表扫描,索引失效了。

 

六、字段类型不同

 

SQL语句中因为字段类型不同,而导致索引失效的问题,很容易遇到,可能是我们日常工作中最容易忽略的问题。

 

到底怎么回事呢?

 

请大家注意观察一下t_user表中的code字段,它是varchar字符类型的。

 

在sql语句中查询数据时,查询条件我们可以写成这样:

 

  •  
  •  
explain select * from user where code="101";

 

执行结果:

 

图片

 

从上图中看到,该code字段走了索引。

 

温馨提醒一下,查询字符字段时,用双引号“和单引号'都可以。

 

但如果你在写SQL时,不小心把引号弄掉了,把SQL语句变成了:

 

  •  
  •  
explain select * from user where code=101;

 

执行结果:

 

图片

 

你会惊奇的发现,该SQL语句竟然变成了全表扫描。因为少写了引号,这种小小的失误,竟然让code字段上的索引失效了。

 

这时你心里可能有一万个为什么,其中有一个肯定是:为什么索引会失效呢?

 

答:因为code字段的类型是varchar,而传参的类型是int,两种类型不同。

 

此外,还有一个有趣的现象,如果int类型的height字段,在查询时加了引号条件,却还可以走索引:

 

  •  
  •  
explain select * from user where height='175';

 

执行结果:

 

图片

 

从图中看出该SQL语句确实走了索引。int类型的参数,不管在查询时加没加引号,都能走索引。

 

这是变魔术吗?这不科学呀。

 

答:MySQL发现如果是int类型字段作为查询条件时,它会自动将该字段的传参进行隐式转换,把字符串转换成int类型。

 

MySQL会把上面列子中的字符串175,转换成数字175,所以仍然能走索引。

 

接下来,看一个更有趣的SQL语句:

 

  •  
select 1 + '1';

 

它的执行结果是2,还是11呢?

 

好吧,不卖关子了,直接公布答案执行结果是2。

 

MySQL自动把字符串1,转换成了int类型的1,然后变成了:1+1=2。

 

但如果你确实想拼接字符串该怎么办?

 

答:可以使用concat关键字。

 

具体拼接SQL如下:

 

  •  
select concat(1,'1');

 

接下来,关键问题来了:为什么字符串类型的字段,传入了int类型的参数时索引会失效呢?

 

答:根据MySQL官网上解释,字符串'1'、' 1 '、'1a'都能转换成int类型的1,也就是说可能会出现多个字符串,对应一个int类型参数的情况。那么,MySQL怎么知道该把int类型的1转换成哪种字符串,用哪个索引快速查值?

 

感兴趣的小伙伴可以再看看官方文档:https://dev.mysql.com/doc/refman/8.0/en/type-conversion.html

 

七、like左边包含%

 

模糊查询,在我们日常的工作中,使用频率还是比较高的。

 

比如现在有个需求:想查询姓李的同学有哪些?

 

使用like语句可以很快的实现:

 

  •  
select * from user where name like '李%';

 

但如果like用的不好,就可能会出现性能问题,因为有时候它的索引会失效。

 

不信,我们一起往下看。

 

目前like查询主要有三种情况:

 

  • like '%a'

  • like 'a%'

  • like '%a%'

 

假如现在有个需求:想查出所有code是10开头的用户。

 

这个需求太简单了吧,SQL语句如下:

 

  •  
  •  
explain select * from userwhere code like '10%';

 

执行结果:

 

图片

 

图中看出这种%在10右边时走了索引。

 

而如果把需求改了:想出现出所有code是1结尾的用户。

 

查询SQL语句改为:

 

  •  
  •  
explain select * from userwhere code like '%1';

 

执行结果:

 

图片

 

从图中看出这种%在1左边时,code字段上索引失效了,该SQL变成了全表扫描。

 

此外,如果出现以下SQL

 

  •  
  •  
explain select * from userwhere code like '%1%';

 

SQL语句的索引也会失效。

 

下面用一句话总结一下规律:当like语句中的%,出现在查询条件的左边时,索引会失效。

 

那么,为什么会出现这种现象呢?

 

答:其实很好理解,索引就像字典中的目录。一般目录是按字母或者拼音从小到大,从左到右排序,是有顺序的。

 

我们在查目录时,通常会先从左边第一个字母进行匹对,如果相同,再匹对左边第二个字母,如果再相同匹对其他的字母,以此类推。

 

通过这种方式我们能快速锁定一个具体的目录,或者缩小目录的范围。

 

但如果你硬要跟目录的设计反着来,先从字典目录右边匹配第一个字母,这画面你可以自行脑补一下,你眼中可能只剩下绝望了,哈哈。

 

八、列对比

 

上面的内容都是常规需求,接下来,来点不一样的。

 

假如我们现在有这样一个需求:过滤出表中某两列值相同的记录。比如user表中id字段和height字段,查询出这两个字段中值相同的记录。

 

这个需求很简单,SQL可以这样写:

 

  •  
  •  
explain select * from user where id=height

 

执行结果:

 

图片

 

意不意外,惊不惊喜?索引失效了。

 

为什么会出现这种结果?

 

id字段本身是有主键索引的,同时height字段也建了普通索引的,并且两个字段都是int类型,类型是一样的。

 

但如果把两个单独建了索引的列,用来做列对比时索引会失效。

 

感兴趣的朋友可以找我私聊。

 

九、使用or关键字

 

我们平时在写查询SQL时,使用or关键字的场景非常多,但如果你稍不注意,就可能让已有的索引失效。

 

不信一起往下面看。

 

某天你遇到这样一个需求:想查一下id=1或者height=175的用户。

 

你三下五除二就把SQL写好了:

 

  •  
  •  
explain select * from user where id=1 or height='175';

 

执行结果:

 

图片

 

没错,这次确实走了索引,恭喜被你蒙对了,因为刚好id和height字段都建了索引。

 

但接下来的一个夜黑风高的晚上,需求改了:除了前面的查询条件之后,还想加一个address='成都'。

 

这还不简单,SQL走起:

 

  •  
  •  
explain select * from user where id=1 or height='175' or address='成都';

 

执行结果:

 

图片

 

结果悲剧了,之前的索引都失效了。

 

你可能一脸懵逼,为什么?我做了什么?

 

答:因为你最后加的address字段没有加索引,从而导致其他字段的索引都失效了。

 

注意:如果使用了or关键字,那么它前面和后面的字段都要加索引,不然所有的索引都会失效,这是一个大坑。

 

十、not in和not exists

 

在我们日常工作中用得也比较多的,还有范围查询,常见的有:

 

  • in

  • exists

  • not in

  • not exists

  • between and

 

今天重点聊聊前面四种。

 

 
1、in关键字

 

假如我们想查出height在某些范围之内的用户,这时SQL语句可以这样写:

 

  •  
  •  
explain select * from userwhere height in (173,174,175,176);

 

执行结果:

 

图片

 

从图中可以看出,SQL语句中用in关键字是走了索引的。

 

 
2、exists关键字

 

有时候使用in关键字时性能不好,这时就能用exists关键字优化SQL了,该关键字能达到in关键字相同的效果:

 

  •  
  •  
explain select * from user  t1where  exists (select 1 from user t2 where t2.height=173 and t1.id=t2.id)

 

执行结果:

 

图片

 

从图中可以看出,用exists关键字同样走了索引。

 

 
3、not in关键字

 

上面演示的两个例子是正向的范围,即在某些范围之内。

 

那么反向的范围,即不在某些范围之内,能走索引不?

 

话不多说,先看看使用not in的情况:

 

  •  
  •  
explain select * from userwhere height not in (173,174,175,176);

 

执行结果:

 

图片

 

你没看错,索引失效了。

 

看如果现在需求改了:想查一下id不等于1、2、3的用户有哪些,这时SQL语句可以改成这样:

 

  •  
  •  
explain select * from userwhere id  not in (173,174,175,176);

 

执行结果:

 

图片

 

你可能会惊奇的发现,主键字段中使用not in关键字查询数据范围,任然可以走索引。而普通索引字段使用了not in关键字查询数据范围,索引会失效。

 

 
4、not exists关键字

 

除此之外,如果SQL语句中使用not exists时,索引也会失效。具体SQL语句如下:

 

  •  
  •  
explain select * from user  t1where  not exists (select 1 from user t2 where t2.height=173 and t1.id=t2.id)

 

执行结果:

 

图片

 

从图中看出SQL语句中使用not exists关键后,t1表走了全表扫描,并没有走索引。

 

十一、order by的坑

 

SQL语句中,对查询结果进行排序是非常常见的需求,一般情况下我们用关键字:order by就能搞定。

 

但我始终觉得order by挺难用的,它跟where或者limit关键字有很多千丝万缕的联系,一不小心就会出问题。

 

Let go

 

 
1、哪些情况走索引?

 

首先当然要温柔一点,一起看看order by的哪些情况可以走索引。

 

我之前说过,在code、age和name这3个字段上,已经建了联合索引:idx_code_age_name。

 

1)满足最左匹配原则

 

order by后面的条件,也要遵循联合索引的最左匹配原则。具体有以下SQL

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
explain select * from userorder by code limit 100;
explain select * from userorder by code,age limit 100;
explain select * from userorder by code,age,name limit 100;

 

执行结果:

 

图片

 

从图中看出这3条SQL都能够正常走索引。

 

除了遵循最左匹配原则之外,有个非常关键的地方是,后面还是加了limit关键字,如果不加它索引会失效。

 

2)配合where一起使用

 

order by还能配合where一起遵循最左匹配原则。

 

  •  
  •  
  •  
explain select * from userwhere code='101'order by age;

 

执行结果:

 

图片

 

code是联合索引的第一个字段,在where中使用了,而age是联合索引的第二个字段,在order by中接着使用。

 

假如中间断层了,SQL语句变成这样,执行结果会是什么呢?

 

  •  
  •  
  •  
explain select * from userwhere code='101'order by name;

 

执行结果:

 

图片

 

虽说name是联合索引的第三个字段,但根据最左匹配原则,该SQL语句依然能走索引,因为最左边的第一个字段code,在where中使用了。只不过order by的时候,排序效率比较低,需要走一次filesort排序罢了。

 

3)相同的排序

 

order by后面如果包含了联合索引的多个排序字段,只要它们的排序规律是相同的(要么同时升序,要么同时降序),也可以走索引。

 

具体sql如下:

 

  •  
  •  
explain select * from userorder by code desc,age desc limit 100;

 

执行结果:

 

图片

 

该示例中order by后面的code和age字段都用了降序,所以依然走了索引。

 

4)两者都有

 

如果某个联合索引字段,在where和order by中都有,结果会怎么样?

 

  •  
  •  
  •  
explain select * from userwhere code='101'order by code, name;

 

执行结果:

 

图片

 

code字段在where和order by中都有,对于这种情况,从图中的结果看出,还是能走了索引的。

 

 
2、哪些情况不走索引?

 

前面介绍的都是正面的用法,是为了让大家更容易接受下面反面的用法。

 

好了,接下来,重点聊聊order by的哪些情况下不走索引?

 

1)没加where或limit

 

如果order by语句中没有加where或limit关键字,该SQL语句将不会走索引。

 

  •  
  •  
explain select * from userorder by code, name;

 

执行结果:

 

图片

 

从图中看出索引真的失效了。

 

2)对不同的索引做order by

 

前面介绍的基本都是联合索引,这一个索引的情况。但如果对多个索引进行order by,结果会怎么样呢?

 

  •  
  •  
explain select * from userorder by code, height limit 100;

 

执行结果:

 

图片

 

从图中看出索引也失效了。

 

3)不满足最左匹配原则

 

前面已经介绍过,order by如果满足最左匹配原则,还是会走索引。下面看看,不满足最左匹配原则的情况:

 

  •  
  •  
explain select * from userorder by name limit 100;

 

执行结果:

 

图片

 

name字段是联合索引的第三个字段,从图中看出如果order by不满足最左匹配原则,确实不会走索引。

 

4)不同的排序

 

前面已经介绍过,如果order by后面有一个联合索引的多个字段,它们具有相同排序规则,那么会走索引。

 

但如果它们有不同的排序规则呢?

 

  •  
  •  
explain select * from userorder by code asc,age desc limit 100;

 

执行结果:

 

图片

 

从图中看出,尽管order by后面的code和age字段遵循了最左匹配原则,但由于一个字段是用的升序,另一个字段用的降序,最终会导致索引失效。

 

好了今天分享的内容就先到这里,我们下期再见。

 

作者丨苏三呀
来源丨公众号:苏三说技术(ID:susanSayJava)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

CPU被挖矿,Redis竟是内鬼

一、祸从天降

 

却说这一日,Redis正如往常一般工作,不久便收到了一条SAVE命令。

 

虽说这Redis常被用来当做缓存,数据只存在于内存中,却也能通过SAVE命令将内存中的数据保存到磁盘文件中以便持久化存储。

 

图片

 

只见Redis刚打开文件,准备写入,不知何处突然冲出几个大汉将其擒住。

 

到底是怎么回事?Redis一脸懵。

 

这事还得要从一个月之前说起。

 

二、前情回顾

 

一个月前,Linux帝国......

 

夜已深了,安全警报突然再一次响了起来。

 

“部长,rm那小子是假冒的,今天他骗了我们,挖矿病毒根本没删掉,又卷土重来了!”

 

安全部长望向远处的天空,CPU工厂门口的风扇又开始疯狂地转了起来···

 

无奈之下,部长只好再次召集大家。

 

unhide再一次拿出看家本领,把潜藏的几个进程给捉了出来。kill老哥拿着他们的pid,手起刀落,动作干脆利落。

 

这一次,没等找到真正的rm,部长亲自动手,清理了这几个程序文件。

 

“部长,总这么下去不是个办法,删了又来,得想个长久之计啊!”,一旁的top说到。

 

“一定要把背后的真凶给揪出来!”,ps说到。

 

“它们是怎么混进来的,也要调查清楚!”,netstat说到。

 

“对,对,就是”,众人皆附和。

 

部长起身说道,“大家说得没错,在诸位到来之前,我已经安排助理去核查了,相信很快会有线索。”

 

此时,防火墙上前说道:“为了防止走漏消息,建议先停掉所有的网络连接”

 

“也罢,这三更半夜的,对业务影响也不大,停了吧!”,安全部长说到。

 

不多时,助理行色匆匆地赶了回来,在部长耳边窃窃私语一番,听得安全部长瞬时脸色大变。

 

“sshd留一下,其他人可以先撤了”,部长说到。

 

大伙先后散去,只留下sshd,心里不觉忐忑了起来。

 

“等一下,kill也留一下”,部长补充道。

 

一听这话,sshd心跳的更加快了。

 

图片

 

助理关上了大门,安全部长轻声说到:“据刚刚得到的消息,有人非法远程登录了进来,这挖矿病毒极有可能就是被人远程上传了进来”

 

sshd一听这话大惊失色,慌忙问道:“难道登录密码泄露了?”

 

“应该不是,是使用的公私钥免密登录”,一旁的助理回答到。

 

“你看,在/root/.ssh/authorized_keys文件中,我们发现了一个新的登录公钥,这在之前是没有的”,随后,助理输出了这文件的内容:

 

  •  
  •  
[root@xuanyuan ~]# cat .ssh/authorized_keysssh-rsa AAAAB3NzaC1yc2EAAAADAQABA······

 

“绝不是我干的”,sshd急忙撇清。

 

“远程登录,这不是你负责的业务吗?”,助理问到。

 

“确实是我负责,但我也只是按程序办事,他能用公私钥登录的前提是得先把公钥写入进来啊,所以到底是谁写进来的,这才是关键!”,sshd说到。

 

“说的没错,别紧张,想想看,有没有看到过谁动过这个文件?”,部长拍了下sshd的肩膀说到。

 

“这倒是没留意”

 

部长紧锁眉头,来回走了几步,说道:“那好,这公钥我们先清理了。回去以后盯紧这个文件,有人来访问立刻报给我”

 

“好的”,sshd随后离开,发现自己已经吓出了一身冷汗。

 

三、凶手浮现

 

时间一晃,一个月就过去了。

 

自从把authorized_keys文件中的公钥清理后,Linux帝国总算是太平了一阵子,挖矿病毒入侵事件也渐渐被人淡忘。

 

这天晚上夜已深,sshd打起了瞌睡。

 

图片

 

突然,“咣当”一声,sshd醒了过来,睁眼一看,竟发现有程序闯入了/root/.ssh目录!

 

这一下sshd睡意全无,等了一个多月,难道这家伙要现身了?

 

sshd不觉紧张了起来,到底会是谁呢?

 

此刻,sshd紧紧盯着authorized_keys文件,眼睛都不敢眨一下,生怕错过些什么。

 

图片

 

果然,一个身影走了过来,径直走向这个文件,随后打开了它!

 

sshd不敢犹豫,赶紧给安全部长助理发去了消息。

 

那背影转过身来,这一下sshd看清了他的容貌,竟然是Redis!

 

收到消息的部长带人火速赶了过来,不等Redis写入数据,就上前按住了他。

 

“好家伙,没想到内鬼居然是你!”,sshd得意的说到。

 

Redis看着众人,一脸委屈,“你们这是干什么?我也没做什么坏事啊”

 

“人赃并获,你还抵赖?说吧,你为什么要来写authorized_keys文件?”

 

“那是因为我要来执行数据持久化存储,把内存中的数据写到文件中保存”,Redis答道。

 

“你持久化存储,为什么会写到authorized_keys文件里面来?”,sshd继续质问。

 

“刚刚收到几条命令,设置了持久化存储的文件名就是这个,不信你看”,说罢,Redis拿出了刚刚收到的几条命令:

 

  •  
  •  
  •  
CONFIG SET dir /root/.sshCONFIG SET dbfilename authorized_keysSAVE

 

“第一条指定保存路径,第二条指定保存的文件名,第三条就是保存数据到文件了”,Redis继续解释到。

 

安全部长仔细看着几条命令,说道:“把你要写入的数据给我看看”

 

“这可有点多,你等一下”,说罢,Redis拿出了所有的键值数据,散落一地。

 

图片

 

众人在一大片数据中看花了眼。

 

“部长快看!”,sshd突然大叫。

 

顺着他手指的方向,一个醒目的公钥出现在了大家面前。

 

  •  
ssh-rsa AAAAB3NzaC1yc2EAA···

 

“果然是你!”

 

Redis还是一脸懵,还不知发生了什么。

 

“你这家伙,被人当枪使了!你写的这个文件可不是普通文件,你这要是写进去了,别人就能远程登录进来了,之前的挖矿病毒就是这么进来的!”,sshd说到。

 

一听这话,Redis吓得赶紧掐断了网络连接。

 

“给你下命令的究竟是谁,又是怎么连接上你的?”,部长问到。

 

Redis不好意思的低下了头,只说道:“不瞒您说,我这默认就没有密码,谁都可以连进来”

 

安全部长听得眼睛都瞪圆了,愤而离去。

 

只听得一声大叫,kill老哥又一次手起刀落。

 

四、彩蛋

 

“部长,不好了”

 

“什么事,慌慌张张的”

 

“我的数据全都被加密了!”,MySQL气喘吁吁的说到···

 

作者丨轩辕之风O
来源丨公众号:编程技术宇宙(ID:xuanyuancoding)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

干了一辈子,到今天才摸透运维的职业方向……

一、前言

 

图片

 

互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够7×24小时为用户提供高质量的服务。

 

运维人员对公司互联网业务所依赖的基础设施、基础服务、线上业务进行稳定性加强,进行日常巡检发现服务可能存在的隐患,对整体架构进行优化以屏蔽常见的运行故障,多数据中接入提高业务的容灾能力,通过监控、日志分析等技术手段,及时发现和响应服务故障,减少服务中断的时间,使公司的互联网业务符合预期的可用性要求,持续稳定地为用户提供务。

 

在安全方面,运维人员需要关注业务运行所涉及的各个层面,确保用户能够安全、完整地访问在线业务。从网络边界划分、ACL管理、流量分析、DDoS防御,到操作系统、开源软件的漏洞扫描和修补,再到应用服务的XSS、SQL注入防护;从安全流程梳、代码白盒黑盒扫描、权限审计,到入侵行为检测、业务风险控制等。运维人员需要保障公司提供的互联网业 运行在安全、可控的状态下,确保公司业务数据和用户隐私数据的安全,同时还需要具备抵御各种恶意攻击的能力。

 

在确保业务稳定、安全的前提下,还需保障业务高效的运转,公司内快速的产出。运维工作需要对业务进行各方面优化,比如,IO优化提升数据库性能,图片压缩降低带宽使用量等,提供的互联网业务以较小的资源投入带来最大的用户价值和体验。同时,还需要通过各种工具平台提升内部产品发布交付的效率,提升公司内运维相关的工作效率。

 

二、运维工作分类

 

运维的工作方向比较多,随着业务规模的不断发展,越成熟的互联网公司,运维岗位会划分得越细。当前很多大型的互联网公司,在初创时期只有系统运维,随着规模、服务质量的要求,也逐渐进行了工作细分。一般情况下运维团队的工作分类(见图1-1)和职责如下。

 

图片

图1-1 运维团队的工作分类

 

 
1、系统运维

 

系统运维负责IDC、网络、CDN和基础服务的建设(LVS、NTP、DNS);负责资产管理,服务器选型、交付和维修。详细的工作职责如下:

 

1)IDC数据中心建设

 

收集业务需求,预估未来数据中心的发展规模,从骨干网的分布、数据中心建筑,以及Internet接入、网络攻击防御能力、扩容能力、空间预留、外接专线能力、现场服务支撑能力等方面评估选型数据中心。负责数据中心的建设、现场维护工作。

 

2)网络建设

 

设计及规划生产网络架构,这里面包括:数据中心网络架构、传输网架构、CDN网络架构等,以及网络调优等日常运维工作。

 

3)LVS负载均衡和SNAT建设

 

LVS是整个站点架构中的流量入口,根据网络规模和业务需求,构建负载均衡集群;完成网络与业务服务器的衔接,提供高性能、高可用的负载调度能力,以及统一的网络层防攻击能力;SNAT集中提供数据中心的公网访问服务,通过集群化部署,保证出网服务的高性能与高可用。

 

4)CDN规划和建设

 

CDN工作划分为第三方和自建两部分。建立第三方CDN的选型和调度控制;根据业务发展趋势,规划CDN新节点建设布局;完善CDN业务及监控,保障CDN系统稳定、高效运行;分析业务加速频道的文件特性和数量,制定最优的加速策略和资源匹配;负责用户劫持等CDN日常故障排查工作。

 

5)服务器选型、交付和维护

 

负责服务器的测试选型,包含服务器整机、部件的基础性测试和业务测试,降低整机功率,提升机架部署密度等。结合对公司业务的了解,推广新硬件、新方案减少业务的服务器投入规模。负责服务器硬件故障的诊断定位,服务器硬件监控、健康检查工具的开发和维护。

 

6)OS、内核选型和OS相关维护工作

 

负责整体平台的OS选型、定制和内核优化,以及Patch的更新和内部版本发布;建立基础的YUM包管理和分发中心,提供常用包版本库;跟进日常各类OS相关故障;针对不同的业务类型,提供定向的优化支持。

 

7)资产管理

 

记录和管理运维相关的基础物理信息,包括数据中心、网络、机柜、服务器、ACL、IP等各种资源信息,制定有效的流程,确保信息的准确性;开放API接口,为自动化运维提供数据支持。

 

8)基础服务建设

 

业务对DNS、NTP、SYSLOG等基础服务的依赖非常高,需要设计高可用架构避免单点,提供稳定的基础服务。

 

 
2、应用运维

 

应用运维负责线上服务的变更、服务状态监控、服务容灾和数据备份等工作,对服务进行例行排查、故障应急处理等工作。详细的工作职责如下所述。

 

1)设计评审

 

在产品研发阶段,参与产品设计评审,从运维的角度提出评审意见,使服务满足运维准入的高可用要求。

 

2)服务管理

 

负责制定线上业务升级变更及回滚方案,并进行变更实施。掌握所负责的服务及服务间关联关系、服务依赖的各种资源。能够发现服务上的缺陷,及时通报并推进解决。制定服务稳定性指标及准入标准,同时不断完善和优化程序和系统的功能、效率,提高运行质量、完善监控内容,提高报警准确度。在线上服务出现故障时,第一时间响应,对已知线上故障能按流程进行通报并按预案执行,未知故障组织相关人员联合排障。

 

3)资源管理

 

对各服务的服务器资产进行管理,梳理服务器资源状况、数据中心分布情况、网络专线及带宽情况,能够合理使用服务器资源,根据不同服务的需求,分配不同配置的服务器,确保服务器资源的充分利用。

 

4)例行检查

 

制定服务例行排查点,并不断完善。根据制定的服务排查点,对服务进行定期检查。对排查过程中发现的问题,及时进行追查,排除可能存在的隐患。

 

5)预案管理

 

确定服务所需的各项监控、系统指标的阈值或临界点,以及出现该情况后的处理预案。建立和更新服务预案文档,并根据日常故障情况不断补充完善,提高预案完备性。能够制定和评审各类预案,周期性进行预案演练,确保预案的可执行性。

 

6)数据备份

 

制定数据备份策略,按规范进行数据备份工作。保证数据备份的可用性和完整性,定期开展数据恢复性测试。

 

 
3、数据库运维

 

数据库运维负责数据存储方案设计、数据库表设计、索引设计和SQL优化,对数据库进行变更、监控、备份、高可用设计等工作。详细的工作职责如下所述。

 

1)设计评审

 

在产品研发初始阶段,参与设计方案评审,从DBA的角度提出数据存储方案、库表设计方案、SQL开发标准、索引设计方案等,使服务满足数据库使用的高可用、高性能要求。

 

2)容量规划

 

掌握所负责服务的数据库的容量上限,清楚地了解当前瓶颈点,当服务还未到达容量上限时,及时进行优化、分拆或者扩容。

 

3)数据备份与灾备

 

制定数据备份与灾备策略,定期完成数据恢复性测试,保证数据备份的可用性和完整性。

 

4)数据库监控

 

完善数据库存活和性能监控,及时了解数据库运行状态及故障。

 

5)数据库安全

 

建设数据库账号体系,严格控制账号权限与开放范围,降低误操作和数据泄露的风险;加强离线备份数据的管理,降低数据泄露的风险。

 

6)数据库高可用和性能优化

 

对数据库单点风险和故障设计相应的切换方案,降低故障对数据库服务的影响;不断对数据库整体性能进行优化,包括新存储方案引进、硬件优化、文件系统优化、数据库优化、SQL优化等,在保障成本不增加或者少量增加的情况下,数据库可以支撑更多的业务请求。

 

7)自动化系统建设

 

设计开发数据库自动化运维系统,包括数据库部署、自动扩容、分库分表、权限管理、备份恢复、SQL审核和上线、故障切换等功能。

 

8)运维研发

 

运维研发负责通用的运维平台设计和研发工作,如:资产管理、监控系统、运维平台、数据权限管理系统等。提供各种API供运维或研发人员使用,封装更高层的自动化运维系统。详细的工作职责如下所述。

 

9)运维平台

 

记录和管理服务及其关联关系,协助运维人员自动化、流程化地完成日常运维操作,包括机器管理、重启、改名、初始化、域名管理、流量切换和故障预案实施等。

 

10)监控系统

 

负责监控系统的设计、开发工作,完成公司服务器和各种网络设备的资源指标、线上业务运行指标的收集、告警、存储、分析、展示和数据挖掘等工作,持续提高告警的及时性、准确性和智能性,促进公司服务器资源的合理化调配。

 

11)自动化部署系统

 

参与部署自动化系统的开发,负责自动化部署系统所需要的基础数据和信息,负责权限管理、API开发、Web端开发。结合云计算,研发和提供PaaS相关高可用平台,进一步提高服务的部署速度和用户体验,提升资源利用率。

 

 
4、运维安全

 

运维安全负责网络、系统和业务等方面的安全加固工作,进行常规的安全扫描、渗透测试,进行安全工具和系统研发以及安全事件应急处理。详细的工作职责如下所述。

 

1)安全制度建立

 

根据公司内部的具体流程,制定切实可行,且行之有效的安全制度。

 

2)安全培训

 

定期向员工提供具有针对性的安全培训和考核,在全公司内建立安全负责人制度。

 

3)风险评估

 

通过黑白盒测试和检查机制,定期产生对物理网络、服务器、业务应用、用户数据等方面的总体风险评估结果。

 

4)安全建设

 

根据风险评估结果,加固最薄弱的环节,包括设计安全防线、部署安全设备、及时更新补丁、防御病毒、源代码自动扫描和业务产品安全咨询等。为了降低可能泄露数据的价值,通过加密、匿名化、混淆数据,乃至定期删除等技术手段和流程来达到目的。

 

5)安全合规

 

为了满足例如支付牌照等合规性要求,安全团队承担着安全合规的对外接口人工作。

 

6)应急响应

 

建立安全报警系统,通过安全中心收集第三方发现的安全问题,组织各部门对已经发现的安全问题进行修复、影响面评估、事后安全原因追查。

 

三、运维工作发展过程

 

早期的运维团队在人员较少的情况下,主要是进行数据中心建设、基础网络建设、服务器采购和服务器安装交付工作。几乎很少涉及线上服务的变更、监控、管理等工作。这个时候的运维团队更多的属于基础建设的角色,提供一个简单、可用的网络环境和系统环境即可。

 

随着业务产品的逐渐成熟,对于服务质量方面就有了更高的要求。这个时候的运维团队还会承担一些服务器监控的工作,同时会负责LVS、Nginx等与业务逻辑无关的4/7层运维工作。这个时候服务变更更多的是逐台的手工操作,或者有一些简单批量脚本的出现。监控的焦点更多的在服务器状态和资源使用情况上,对服务应用状态的监控几乎很少,监控更多的使用各种开源系统如Nagios、Cacti等。

 

由于业务规模和复杂度的持续增加,运维团队会逐渐划分为应用运维和系统运维两大块。应用运维开始接手线上业务,逐步开展服务监控梳理、数据备份以及服务变更的工作。随着对服务的深入,应用运维工程师有能力开始对服务进行一些简单的优化。同时,为了应对每天大量的服务变更,我们也开始编写各类运维工具,针对某些特定的服务能够很方便的批量变更。随着业务规模的增大,基础设施由于容量规划不足或抵御风险能力较弱导致的故障也越来越多,迫使运维人员开始将更多的精力投入到多数据中心容灾、预案管理的方向上。

 

业务规模达到一定程度后,开源的监控系统在性能和功能方面,已经无法满足业务需求;大量的服务变更、复杂的服务关系,以前靠人工记录、工具变更的方式不管在效率还是准确性方面也都无法满足业务需求;在安全方面也出现了各种大大小小的事件,迫使我们投入更多的精力在安全防御上。逐渐的,运维团队形成之前提到的5个大的工作分类,每个分类都需要有专精的人才。这个时候系统运维更专注于基础设施的建设和运维,提供稳定、高效的网络环境,交付服务器等资源给应用运维工程师。应用运维更专注于服务运行状态和效率。数据库运维属于应用运维工作的细化,更专注于数据库领域的自动化、性能优化和安全防御。运维研发和运维安全提供各类平台、工具,进一步提升运维工程师的工作效率,使业务服务运行得更加稳定、高效和安全。

 

我们将运维发展过程划分为4个阶段,如图1-2所示。

 

图片

图1-2 运维发展过程

 

手工管理阶段:业务流量不大,服务器数量相对较少,系统复杂度不高。对于日常的业务管理操作,大家更多的是逐台登录服务器进行手工操作,属于各自为战,每个人都有自己的操作方式,缺少必要的操作标准、流程机制,比如业务目录环境都是各式各样的。

 

工具批量操作阶段:随着服务器规模、系统复杂度的增加,全人工的操作方式已经不能满足业务的快速发展需要。因此,运维人员逐渐开始使用批量化的操作工具,针对不同操作类型出现了不同的脚本程序。但各团队都有自己的工具,每次操作需求发生变化时都需要调整工具。这主要是因为对于环境、操作的规范不够,导致可程序化处理能力较弱。此时,虽然效率提升了一部分,但很快又遇到了瓶颈。操作的质量并没有太多的提升,甚至可能因为批量执行而导致更大规模的问题出现。我们开始建立大量的流程规范,比如复查机制,先上线一台服务器观察10分钟后再继续后面的操作,一次升级完成后至少要观察20分钟等。这些主要还是靠人来监督和执行,但在实际过程中执行往往不到位,反而降低了工作效率。

 

平台管理阶段:在这个阶段,对于运维效率和误操作率有了更高的要求,我们决定开始建设运维平台,通过平台承载标准、流程,进而解放人力和提高质量。这个时候对服务的变更动作进行了抽象,形成了操作方法、服务目录环境、服务运行方式等统一的标准,如程序的启停接口必须包括启动、停止、重载等。通过平台来约束操作流程,如上面提到的上线一台服务器观察10分钟。在平台中强制设定暂停检查点,在第一台服务器操作完成后,需要运维人员填写相应的检查项,然后才可以继续执行后续的部署动作。

 

系统自调度阶段:更大规模的服务数量、更复杂的服务关联关系、各个运维平台的林立,原有的将批量操作转化成平台操作的方式已经不再适合,需要对服务变更进行更高一层的抽象。将每一台服务器抽象成一个容器,由调度系统根据资源使用情况,将服务调度、部署到合适的服务器上,自动化完成与周边各个运维系统的联动,比如监控系统、日志系统、备份系统等。通过自调度系统,根据服务运行情况动态伸缩容量,能够自动化处理常见的服务故障。运维人员的工作也会前置到产品设计阶段,协助研发人员改造服务使其可以接入到自调度系统中。

 

在整个运维的发展过程中,希望所有的工作都自动化起来,减少人的重复工作,降低知识传递的成本,使我们的运维交付更高效、更安全,使产品运行更稳定。对于故障的处理,也希望由事后处理变成提前发现,由人工处理变成系统自动容灾。

 

作者丨laiwei
来源丨公众号:51reboot运维开发(ID:Reboot51)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

糟糕程序员的20个坏习惯,你命中几个?

前言

 

今天我想和你聊一聊优秀程序员的基本素养。

 

我想你肯定遇到过这样一类程序员:他们无论是写代码,还是写文档,又或是和别人沟通,都显得特别专业。每次遇到这类人,我都在想,他们到底是怎么做到的?

 

随着工作时间的增长,渐渐地我也总结出一些经验,他们身上都保持着一些看似很微小的优秀习惯,但正是因为这些习惯,体现出了一个优秀程序员的基本素养。

 

糟糕程序员的坏习惯

 

但今天我们来换个角度,来看看一个糟糕程序员有哪些坏习惯?只要我们都能避开这些问题,就可以逐渐向一个优秀程序员靠近。

 

1、技术名词拼写不规范
 

 

无论是个人简历,还是技术文档,我经常看到拼写不规范的技术名词,例如 JAVA、javascript、python、MySql、Hbase、restful。

 

正确的拼写应该是 Java、JavaScript、Python、MySQL、HBase、RESTful,不要小看这个问题,很多面试官很有可能因为这一点刷掉你的简历。

 

2、写文档,中英文混排不规范
 

 

中文描述使用英文标点符号,英文和数字使用了全角字符,中文与英文、数字之间没有空格等等。

 

其中很多人会忽视中文和英文、数字之间加一个「空格」,这样排版阅读起来会更舒服。之前我的文章排版,都是遵循了这些细节。

 

3、重要逻辑不写注释,或写得很拖沓
 

 

复杂且重要的逻辑代码,很多程序员不写注释,除了自己能看懂代码逻辑,其他人根本看不懂。或者是注释虽然写了,但写得很拖沓,没有逻辑可言。

 

重要的逻辑不止要写注释,还要写得简洁、清晰。如果是一眼就能读懂的简单代码,可以不加注释。

 

4、写复杂冗长的函数
 

 

一个函数几百行,一个文件上千行代码,复杂函数不做拆分,导致代码变得越来越难维护,最后谁也不敢动。

 

基本的设计模式还是要遵守的,例如单一职责,一个函数只做一件事,开闭原则,对扩展开放,对修改关闭。

 

如果函数逻辑确实复杂,也至少要保证主干逻辑足够清晰。

 

5、不看官方文档,只看垃圾博客
 

 

很多人遇到问题不先去看官方文档,而是热衷于去看垃圾博客,这些博客的内容都是互相抄袭,错误百出。

 

其实很多软件官方文档写得已经非常好了,常见问题都能找到答案,认真读一读官方文档,比看垃圾博客强一百倍,要养成看官方文档的好习惯。

 

6、宣扬内功无用论
 

 

有些人天天追求日新月异的开源项目和框架,却不肯花时间去啃一啃底层原理,常见问题虽然可以解决,但遇到稍微深一点的问题就束手无策。

 

很多高大上的架构设计,思路其实都源于底层。想一想,像计算机体系结构、操作系统、网络协议这些东西,经过多少年演进才变为现在的样子,演进过程中遇到的复杂问题比比皆是,理解了解决这些问题的思路,再看上层技术会变得很简单。

 

7、乐于炫技
 

 

有些人天天把「高大上」的技术名词挂在嘴边,生怕别人不知道自己学了什么高深技术,嘴上乐于炫技,但别人一问他细节就会哑口无言。

 

8、不接受质疑
 

 

自己设计的方案,别人提出疑问时只会回怼,而不是理性分析利弊,抱着学习的心态交流。

 

这些人学了点东西就觉得自己很有本事,殊不知只是自己见识太少。

 

9、接口协议不规范
 

 

和别人定 API 协议全靠口头沟通,不给规范的文档说明,甚至到了测试联调时会发现,竟然和协商的还不一样,或者改协议了却不通知对接方,合作体验极差。

 

10、遇到问题自己死磕
 

 

很初级程序员容易犯的问题,遇到问题只会自己死磕,拖到 deadline 也没有产出,领导来问才知道有问题解决不了。

 

有问题及时反馈才是对自己负责,对团队负责。

 

11、一说就会,一写就废
 

 

平时技术方案吹得天花乱坠,一让他写代码就废,典型的眼高手低选手。

 

12、表达没有逻辑,不站在对方角度看问题
 

 

讨论问题不交代背景,上来就说自己的方案,别人听得云里雾里,让你从头描述你又讲不明白。

 

学会沟通和表达,是合作的基础。

 

13、不主动思考,伸手党
 

 

遇到问题不去 google,不做思考就向别人提问,喜欢做伸手党。

 

每个人的时间都很宝贵,大家都更喜欢你带着自己的思考来提问,一来可以规避很多低级问题,二来可以提高交流质量。

 

14、经常犯重复的错误
 

 

出问题后说下次会注意,但下次问题依旧,对自己不负责任,说到底是态度问题。

 

15、加功能不考虑扩展性
 

 

加新功能只关注某一小块业务,不考虑系统整体的扩展性,堆代码行为严重。

 

要学会分析需求和未来可能发生的变化,设计更通用的解决方案,降低后期开发成本。

 

16、接口不自测,出问题不打日志
 

 

自己开发的接口不自测就和别人联调,出了问题又说没打日志,协作效率极低。

 

17、提交代码不规范
 

 

很多人提交代码不写描述,或者写的是无意义的描述,尤其是修改很少代码时,这种情况会导致回溯问题成本变高。

 

制定代码提交规范,能让你在每一次提交代码时,不会做太随意的代码修改。

 

18、手动修改生产环境数据库
 

 

直连生产环境数据库修改数据,更有 UPDATE / DELETE SQL 忘写 WEHRE 条件的情况,产生数据事故。

 

修改生产环境数据库一定要谨慎再谨慎,建议操作前先找同事 review 代码再操作。

 

19、没理清需求就直接写代码
 

 

很多程序员接到需求后,不怎么思考就开始写代码,需求和自己理解的有偏差,造成无意义返工。

 

多花些时间梳理需求,能规避很多不合理的问题。

 

20、重要设计不写文档
 

 

重要的设计没有文档输出,和别人交接系统时只做口头描述,丢失关键信息。

 

有时候理解一个设计方案,一个好的文档要比看几百行代码更高效。

 

总结

 

以上这些不良习惯,你命中几个呢?或者你身边有没有碰到这样的人?

 

我认为提早规避这些问题,是成为一个优秀程序员必须要做的。这些习惯总结起来大致分为这 4 个方面:

 

  • 良好的编程修养

  • 谦虚的学习心态

  • 良好的沟通和表达

  • 注重团队协作

 

优秀程序员的专业技能,我们可能很难在短时间内学会,但这些基本的职业素养,是可以在短期内做到的。

 

希望你我可以有则改之,无则加勉。

 

你认为还有哪些程序员的坏习惯,欢迎在评论区留言讨论~

 

作者丨Kaito
来源丨公众号:水滴与银弹(ID:waterdrop_bullet)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

春节运维自救手册:能解决80%故障的排查思路

在讲解事件、故障处理思路前,先讲一个故障场景(以呼叫中心系统作为一例子):

 

业务人员反映呼叫中心系统运行缓慢,部份电话在自助语言环节系统处理超时,话务转人工座席,人工座席出现爆线情况。

 

运维人员开始忙活了,查资源使用情况、查服务是否正常、查日志是否报错、查交易量还有没有……时间不知不觉的在敲键盘、敲键盘、敲键盘中过去,但是原因还未定位。

 

经理过来了解情况:“系统恢复了吗?”、“故障影响是什么?”、“交易中断了吗?”……

 

运维人员赶紧敲键盘,写 SQL,看交易量;敲键盘,写命令,看系统资源、情况……

 

最终,定位到问题原因是其中一个功能没有控制返回数量,导致内存泄露。

 

针对这个故障,业务希望运维能否更快的解决故障的恢复,经理希望制定优化呼叫中心故障处理流程,做了以下几件事:

 

优先故障处理过程的时间:”能通过鼠标完成的工作,不要用键盘“

 

提前发现故障,加强监控:“技术早于业务发现问题,监控不仅是报警,还要协助故障定位”

 

完善故障应急方案:“应急方案是最新的、准确的、简单明了的”

 

长远目标:故障自愈:“能固化的操作自动化,能机器做的让机器做”

 

下面将从故障常见的处理方法开始介绍,再从故障前的准备工作(完善监控、制定应急方案等方式)来解决经理提出的问题,并提出未来解决故障的想法。