数据库相关

  • 记录数据库相关的疑难杂症

目录

neo4j

  • 1.通讯协议:

    • Q:  为什么图库使用 neo4j 的 bolt 链接协议,出现了无法找到主节点导致无法写入或者读取的问题?
    • A:neo4j支持3种通讯协议:
  • 2.数据接入

    • Q:  为什么出现hive数据无法接入图库?datax是否支持mysql 导入neo4j ? 什么类型的数据接入可以导入到neo4j?
    • A: 不支持;不支持;目前图平台只支持文件模式导入数据到图平台
  • 3.数据库命名规范:

    • Q:  为什么出现了图数据库创建失败的问题?
    • A:neo4j 有自己的数据库规范,这里需要按照neo4j的规范进行创建,所以对应的图实例也要按照规范进行校验
  • 4.边关系查询缓慢:

  • 5.neo4j 的数据库链接泄露,句柄数量增长非常快

    • A:数据库链接没有及时释放导致的数据库链接泄露,及时释放neo4j的连接即可
      • 微服务句柄数量超过限制问题汇总
  • 7.neo4j 在使用ETL导入时,出现死锁现象:

    • Q: 在使招行AI实验室项目中,图平台[3.1.2.69] 用spark 集群对neo4j批量导入关系边数据的时候,总是会出现报错:ForsetiClient can’t acquire ExclusiveLock(参考:https://github.com/neo4j/neo4j/issues/6248)

    • A:

      • 在使用集群导数,一般是多个作业实例执行导入任务,这里就会出现并发写入的场景。neo4j的边关系写入的操作时,数据库本身会给每一个写入操作的事务分配一把排它锁(exclusiveLock),多并发写入就会出现事务之间锁的争夺情况。在实际的生产环境中观察到,最多有130个事务卡在获取锁,最后导致事务超时,整体数据导入任务失败。

      • 解决方法是:需要降低单次事务写入数据库的数据量。单次写入大量数据非常耗时,从而降低每次事务的耗时,及时将锁资源释放出来,避免发生事务超时的死锁

提高单次事务的超时时间。避免出现多个不同事务之间的锁资源竞争时,没有足够的等待时间,导致的任务失败。
调整taurus-app配置,降低etl任务的spark executor的数量。从源头降低并发,减少锁资源竞争
调整spark配置:[ spark.dynamicAllocation.enabled    false ] ,关闭 动态资源分配功能
调整 etl的spark 任务参数,限制最大:1个instances,1个cores,避免多进程并发写入导致的死锁问题

  • 8.出现报错:Could not perform discovery. No routing servers available

    • A:neo4j 的服务宕机,需要管理员维护
  • 9.使用图平台文件导入大数据量到neo4j宕机

    • A: graph系统在使用文件导入120w条数据,具体表现为会出现jvm内存耗尽,机器不再接受写入请求

    • Q: DBA解释为cypher语句太长,堆积在内存中无法释放导致的内存耗尽,需要优化语句,建议使用unwind优化cypher语句

    • neo4j批量入数优化分析及实现

    1. 数据导入neo4j 出现 heap 堆内存溢出,表现为老年代(old gen)持续增长,不会下降

现象如下图:

  • A:
    • neo4j批量入数优化分析及实现

      • 使用csv文件导数到es和图库。由于csv文件非常巨大,发现2个主要问题:

      • 导数速率很慢,单次只能写入100条数据,如果数据量在50w的实体表,一般就需要耗时1-2小时才能完成导数任务。

      • 在实现导数的方式上有问题,批量导数实现上本质是拼接一个巨长的cypher语句,在小数据量的情况下不会有什么问题。但是如果在大数据量下,会提交很多的长语句,从而会出现neo4j图库无法及时处理这些超长的cypher语句,堆积在JVM的老年代内存中无法释放,最后neo4j出现内存OOM宕机。

    • 优化分析:

      • 在搞清原因之后,咨询DBA了解到,neo4j不建议使用长语句,最好是使用短语句来插入数据,长语句会产生堆积,进而导致内存不足。但是短语句的矛盾就在于性能低下,我们这里需要使用批量插入的模式提高性能。
      • 于是在参考了neo4j-spark的源码实现,得到了启发。neo4j官方sprak的导数实现是使用批量插入的模式,不是通过拼接语句的模式。通过使用参数传递模式进行批量插入,以实体插入为例:
      • scala源码实现(org.neo4j.spark.service.Neo4jQueryWriteStrategy#createStatementForNodes):
      • 编译后的语句:
      • with query: UNWIND $events AS event MERGE (node:Human {object_key: event.keys.object_key}) SET node += event.properties
      • 这里官方实现使用了unwind关键字,这里引用 博文 解释为什么unwind可以加速插入:
      • 高效的做法是利用Neo4j提供的参数(Parameter)机制和UNWIND子句:在一次数据更新中,进行一次连接,打开一次事务,批量更新数据;参数用于提供列表格式的数据,UNWIND子句是把列表数据展开成一行一行的数据,每行数据都会执行结构相同的Cypher语句。再批量更新图形数据之前,用户必须构造结构固定的、参数化的Cypher语句。当Cypher语句的结构相同时,Neo4j数据库直接从缓存中复用已生成的执行计划,而不需要重新生成,这也能够提高查询性能。
      • UNWIND子句把列表式的数据展开成一行一行的数据,每一个行都包含更新所需要的全部信息,列表式的数据,可以通过参数来传递。
      • 例如,定义参数events,该参数是一个JSON字符串,键events是参数名,其值是一个数组,包含两个数组元素。
      1
      2
      3
      {
      "events" : [ { "year" : 2014, "id" : 1}, {"year" : 2014, "id" : 2 } ]
      }
      • 通过$events引用参数,UNWIND子句把events数组中的两个元素展开,每个元素执行一次Cypher语句,由于Cypher的语句结构固定,因此,执行计划被缓存起来,在执行数据更新任务时,参数被UNWIND子句展开,复用执行计划,提高数据更新的速度。
      • 实施方法:实体数据批量插入cypher,采用overwrite模式进行数据创建和合并,依据object_key作为唯一键进行对象合并:
      • 关系边数据批量插入cypher,采用overwrite模式进行数据的创建和合并,依据object_key作为唯一键进行对象合并:

分布式技术原理与算法解析

  • 分布式技术原理与算法解析

目录

  • 选举

  • Bully 算法是一种霸道的集群选主算法,为什么说是霸道呢?因为它的选举原则是“长者”为大,即在所有活着的节点中,选取 ID 最大的节点作为主节点。它的假设条件是,集群中每个节点均知道其他节点的 ID

  • Raft 算法是典型的多数派投票选举算法,其选举机制与我们日常生活中的民主投票机制类似,核心思想是“少数服从多数”。也就是说,Raft 算法中,获得投票最多的节点成为主。

编译原理相关

  • 编译原理相关

目录

antlr4的本地配置安装

    1. 下载antlr到本地机器: wget http://www.antlr.org/download/antlr-4.11.1-complete.jar,将本地JDK版本调整至 JDK-11 或以上版本即可。
    1. 在本地 ~/.bash_profile 添加以下环境变量
1
2
3
4
5
#antlr4
export ANTLR_PATH=/Users/lewis/soft_repo/antlr/antlr-4.11.1-complete.jar
export CLASSPATH=.:$JAVA_HOME/lib:$ANTLR_PATH
alias antlr4='java org.antlr.v4.Tool'
alias grun='java org.antlr.v4.gui.TestRig'
    1. 执行source ~/.bash_profile,刷新当前终端环境变量,输入:antlr4 验证是否成功,如果成功则出现以下信息输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
➜  ~ antlr4
ANTLR Parser Generator Version 4.11.1
-o ___ specify output directory where all output is generated
-lib ___ specify location of grammars, tokens files
-atn generate rule augmented transition network diagrams
-encoding ___ specify grammar file encoding; e.g., euc-jp
-message-format ___ specify output style for messages in antlr, gnu, vs2005
-long-messages show exception details when available for errors and warnings
-listener generate parse tree listener (default)
-no-listener don't generate parse tree listener
-visitor generate parse tree visitor
-no-visitor don't generate parse tree visitor (default)
-package ___ specify a package/namespace for the generated code
-depend generate file dependencies
-D<option>=value set/override a grammar-level option
-Werror treat warnings as errors
-XdbgST launch StringTemplate visualizer on generated code
-XdbgSTWait wait for STViz to close before continuing
-Xforce-atn use the ATN simulator for all predictions
-Xlog dump lots of logging info to antlr-timestamp.log
-Xexact-output-dir all output goes into -o dir regardless of paths/package

巴科斯范式

“巴科斯范式”,简称 BNF。Antlr 和 Yacc 这两个工具都用这种写法。为了简化书写,我有时会在课程中把“::=”简化成一个冒号。你看到的时候,知道是什么意思就可以了。

你有时还会听到一个术语,叫做扩展巴科斯范式 (EBNF)。它跟普通的 BNF 表达式最大的区别,就是里面会用到类似正则表达式的一些写法。比如下面这个规则中运用了 * 号,来表示这个部分可以重复 0 到多次:

K8S 自学总结

部署

模板类型

  • deployment:无状态服务(在线)
  • stateful:有状态服务(在线)
  • batch:离线计算服务
    • CronJob:定时离线任务
    • Job:普通离线任务
  • Ingress:代理不同后端 Service 而设置的负载均衡服务

ElasticSearch源码学习-LTS

  • 用于个人学习总结ElasticSearch
  • 包括基础使用、运行机制、源码解析等
  • 源码基于 6.1 分支: ElasticSearch-6.1分支代码

目录

如何调试

    1. 编译构建elasticsearch工程: ./gradlew assemble
    1. 将工程集成到IDEA: ./gradlew idea,用IDEA打开elasticsearch工程
    1. 执行 ./gradlew :run --debug-jvm,启动调试模式.
    1. debug启动之后,观察日志:[elasticsearch] Listening for transport dt_socket at address: 8000发现debug端口为8000.
    1. 添加远程JVM调试,主机填localhost,端口配置为8000,JDK选择 5-8,点击确定启动debug
  • debug 配置
    1. 可以观察日志,服务已经正常启动
1
2
3
4
5
6
7
8
9
[elasticsearch] [2023-07-26T16:19:14,233][INFO ][o.e.t.TransportService   ] [node-0] publish_address {127.0.0.1:9300}, bound_addresses {[::1]:9300}, {127.0.0.1:9300}
[elasticsearch] [2023-07-26T16:19:17,300][INFO ][o.e.c.s.MasterService ] [node-0] zen-disco-elected-as-master ([0] nodes joined), reason: new_master {node-0}{48qziOzRTdOSQo0nQhQ_PQ}{udw-kDLxTNCvBvup2R2Nqw}{127.0.0.1}{127.0.0.1:9300}{testattr=test}
[elasticsearch] [2023-07-26T16:19:17,304][INFO ][o.e.c.s.ClusterApplierService] [node-0] new_master {node-0}{48qziOzRTdOSQo0nQhQ_PQ}{udw-kDLxTNCvBvup2R2Nqw}{127.0.0.1}{127.0.0.1:9300}{testattr=test}, reason: apply cluster state (from master [master {node-0}{48qziOzRTdOSQo0nQhQ_PQ}{udw-kDLxTNCvBvup2R2Nqw}{127.0.0.1}{127.0.0.1:9300}{testattr=test} committed version [1] source [zen-disco-elected-as-master ([0] nodes joined)]])
[elasticsearch] [2023-07-26T16:19:17,329][INFO ][o.e.g.GatewayService ] [node-0] recovered [0] indices into cluster_state
[elasticsearch] [2023-07-26T16:19:17,331][INFO ][o.e.h.n.Netty4HttpServerTransport] [node-0] publish_address {127.0.0.1:9200}, bound_addresses {[::1]:9200}, {127.0.0.1:9200}
[elasticsearch] [2023-07-26T16:19:17,333][INFO ][o.e.n.Node ] [node-0] started
<============-> 96% EXECUTING [11m 35s]
> :distribution:run#start
> IDLE
    1. 在浏览器访问: http://127.0.0.1:9200/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name" : "node-0",
"cluster_name" : "distribution_run",
"cluster_uuid" : "otLdQ8YGRDuaRDHHW2ly9w",
"version" : {
"number" : "6.1.5",
"build_hash" : "c975590",
"build_date" : "2023-07-13T06:34:36.143Z",
"build_snapshot" : true,
"lucene_version" : "7.1.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}

ES集群启动步骤

    1. 选举主节点(过半数为master节点)
    1. 选举集群元信息
    1. allocation分配数据分片
    1. index recovery 索引重启恢复
    1. 集群启动

ES数据模型

  • 1 数据副本模型基于主从模式(或称主备模式,HDFS和 Cassandra为对等模式),在实现过程中参考了微软的PacificA算法
  • 2 数据副本模型:
    • ES的数据副本模型基于主备模式
    • 每个索引都会被拆分为多个分片,并且每个分片都有多个副本(这些副本称为replication group)
  • 3 写入过程:
    • 请求到达协调节点:(request->coordinator)
    • 协调节点先验证操作:(coordinator->validation)
    • 协调节点转发到主分片(coordinator—>routing to-> master node)
    • 主节点本地更新操作( master node update)
    • 主节点下发数据同步给副本节点组(master node->slave nodes)
    • 一旦所有的副分片成功执行操作并回复主分片,主分片会把 请求执行成功的信息返回给协调节点,协调节点返回给客户端
  • 4 故障处理
    • 出现主分片错误:如离线、磁盘损坏等,会超时(1分钟)之后主动降级,提升一个副分片为主分片
    • 出错的主分片操作会被副分片拒绝:来自陈旧的主分片的操作将会被副分片拒绝。当它接收来自副分片的拒绝其请求的响应时,它将会访问一下(新)主节点,然后就会知道自己已被替换。最后将操作路由到新的主分片。
  • 5 读取模型
    • 把读请求转发到相关分片
    • 从副本组中选择一个相关分片的活跃副本
    • 发送分片级的读请求到被选中的副本
    • 合并结果并给客户端返回响应

ES主分片选举策略

  • 安全地分配主分片
    • 分片决策过程在主节点完成,并记录在集群状态中
    • 为了确保安全,主节点必须确保被选为主分片的副本含有最新数据。为 此,ES 使用 Allocation IDs 的概念,这是区分不同分片的唯一标识
  • 分片时序id(Sequence IDs)
    • 本地及全局检查点(global checkpoint) :全局检查点是所有活跃分片历史都已对齐的序列号,换句话说,所 有低于全局检查点的操作都保证已被所有活跃的分片处理完毕。这意味 着,当主分片失效时,我们只需要比较新主分片与其他副分片之间的最 后一个全局检查点之后的操作即可。当旧主分片恢复时,我们使用它知 道的全局检查点,与新主分片进行比较。这样,我们只有小部分操作需 要比较,不用比较全部
  • _version
    • 1.是实现乐观锁,如同其他数据库的乐观锁一 样。我们在写请求中指定文档的版本号,如果文档的当前版本与请求中 指定的版本号不同,则请求会失败。
    • 2.当文档被修改时版本号递 增。ES 使用这个_version来确保变更以正确顺序执行

ES写入流程

  • 基本流程:

      1. 客户端发出请求到es服务端协调节点
      1. 协调节点确定数据所属分片主节点,将请求路由转发到主分片节点
      1. 主分片节点执行写操作,并将请求写入到副本节点,等待所有副本节点写入成功
      1. 主分片节点向协调节点报告,协调节点向客户端报告成功
    • 写一致性的默认策略是quorum,即多数的分片(其中分片副本可以 是主分片或副分片)在写入操作时处于可用状态。
    • quorum = int((primary + number_of_replicas) / 2 ) + 1
  • 详细流程

ES-GET流程

  • 基本流程:
      1. 客户端请求node节点(coordinator 协调节点)
      1. node节点使用文档id确定数据分片,将请求转发给任意一个分片副本节点
      1. 副本节点返回对应文档数据,node返回数据给客户端
  • 详细流程
    GET详细流程

Search流程

  • 索引和搜索
    索引流程

  • 分布式搜索过程

    • 实现类:org.elasticsearch.rest.action.search.RestSearchAction

Linux应用性能调优-LTS

  • 总结、收集 Linux 实用命令、系统应用调优相关的技巧
  • 本文基于 Ubuntu-22.04、Centos-7 版本

场景

目录

CPU问题分析

CPU问题分析图

内存问题分析

内存问题分析图

磁盘问题分析

磁盘问题分析图

网络问题分析

磁盘问题分析图

系统信息

top

  • [简介]: top (table of processes)是一个任务管理器程序,它可运行于许多类Unix操作系统上,它用于显示有关CPU和内存利用率的信息。

  • us: 用户态使用率

  • sy: 内核态使用率

  • id: 空闲率

  • Mem: 物理内存使用量

  • Swap: 虚拟内存分区使用量

  • 进程关键指标: S 列(也就是 Status 列)含义

    • R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
    • D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
    • Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它表示僵尸进程,也就是 进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
    • I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高,I 状态的进程却不会。
  • VIRT 是进程虚拟内存的大小,只要是进程申请过的内存,即便还没有真正分配物理内存,也会计算在内。

  • RES 是常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括 Swap 和共享内存。

  • SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。

  • %MEM 是进程使用物理内存占系统总内存的百分比。

sar

  • [简介]:sar是System Activity Reporter(系统活动情况报告)的缩写。sar工具将对系统当前的状态进行取样,然后通过计算数据和比例来表达系统的当前运行状态。它的特点是可以连续对系统取样,获得大量的取样数据;取样数据和分析的结果都可以存入文件,所需的负载很小。sar是目前Linux上最为全面的系统性能分析工具之一,可以从14个大方面对系统的活动进行报告,包括文件的读写情况、系统调用的使用情况、串口、CPU效率、内存使用状况、进程活动及IPC有关的活动等,使用也是较为复杂。

  • sar -u : 默认情况下显示的cpu使用率等信息就是sar -u;

    • %user 用户模式下消耗的CPU时间的比例;
    • %nice 通过nice改变了进程调度优先级的进程,在用户模式下消耗的CPU时间的比例
    • %system 系统模式下消耗的CPU时间的比例;
    • %iowait CPU等待磁盘I/O导致空闲状态消耗的时间比例;
    • %steal 利用Xen等操作系统虚拟化技术,等待其它虚拟CPU计算占用的时间比例;
    • %idle CPU空闲时间比例;
  • sar -q: 查看平均负载

    • runq-sz:运行队列的长度(等待运行的进程数)
    • plist-sz:进程列表中进程(processes)和线程(threads)的数量
    • ldavg-1:最后1分钟的系统平均负载 ldavg-5:过去5分钟的系统平均负载
    • ldavg-15:过去15分钟的系统平均负载
  • sar -r: 指定-r之后,可查看物理内存使用状况;

    • kbmemfree:这个值和free命令中的free值基本一致,所以它不包括buffer和cache的空间.
    • kbmemused:这个值和free命令中的used值基本一致,所以它包括buffer和cache的空间.
    • %memused:物理内存使用率,这个值是kbmemused和内存总量(不包括swap)的一个百分比.
    • kbbuffers和kbcached:这两个值就是free命令中的buffer和cache.
    • kbcommit:保证当前系统所需要的内存,即为了确保不溢出而需要的内存(RAM+swap).
    • %commit:这个值是kbcommit与内存总量(包括swap)的一个百分比.
  • sar -W:查看页面交换发生状况

    • pswpin/s:每秒系统换入的交换页面(swap page)数量
    • pswpout/s:每秒系统换出的交换页面(swap page)数量
  • 场景使用

    • 怀疑CPU存在瓶颈,可用 sar -u 和 sar -q 等来查看
    • 怀疑内存存在瓶颈,可用sar -B、sar -r 和 sar -W 等来查看
    • 怀疑I/O存在瓶颈,可用 sar -b、sar -u 和 sar -d 等来查看
  • 参数含义解释

    • -A 汇总所有的报告
    • -a 报告文件读写使用情况
    • -B 报告附加的缓存的使用情况
    • -b 报告缓存的使用情况
    • -c 报告系统调用的使用情况
    • -d 报告磁盘的使用情况
    • -g 报告串口的使用情况
    • -h 报告关于buffer使用的统计数据
    • -m 报告IPC消息队列和信号量的使用情况
    • -n 报告命名cache的使用情况
    • -p 报告调页活动的使用情况
    • -q 报告运行队列和交换队列的平均长度
    • -R 报告进程的活动情况
    • -r 报告没有使用的内存页面和硬盘块
    • -u 报告CPU的利用率
    • -v 报告进程、i节点、文件和锁表状态
    • -w 报告系统交换活动状况
    • -y 报告TTY设备活动状况

watch

  • [简介]: Linux中的watch 命令提供了一种方式处理重复的任务。默认watch会每2秒重复执行命令。你一定也想到了,watch是一个很好的观察log文件的工具。下面是一个例子。
  • 例如执行命令watch -n 1 -d ps 每隔一秒高亮显示进程信息

pidstat

  • [简介]:
  • 样例: 如监控进程pid4344]信息: pidstat -d -p 4344 1 3,-d 展示 I/O 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据
  • 参数含义: kB_rd 表示每秒读的 KB 数, kB_wr 表示每秒写的 KB 数,iodelay 表示 I/O 的延迟(单位是时钟周期)

dstat

  • [简介] dstat 是一个新的性能工具,它吸收了 vmstat、iostat、ifstat 等几种工具的优点,可以同时观察系统的 CPU、磁盘 I/O、网络以及内存使用情况。
  • 安装执行命令 apt install dstat -y

文件磁盘

iostat

  • [简介] iostat 是最常用的磁盘 I/O 性能观测工具,它提供了每个磁盘的使用率、IOPS、吞吐量等各种常见的性能指标,当然,这些指标实际上来自 /proc/diskstats。
  • [样例] iostat -d -x 1
  • 参数含义
  • %util ,就是我们前面提到的磁盘 I/O 使用率;
  • r/s+ w/s ,就是 IOPS;
  • rkB/s+wkB/s ,就是吞吐量;
  • r_await+w_await ,就是响应时间。

iotop

  • [简介] 一个类似于 top 的工具,你可以按照 I/O 大小对进程排序,然后找到 I/O 较大的那些进程
  • [样例] iotop

lsof

  • [简介] 用于查看你进程打开的文件,打开文件的进程,进程打开的端口(TCP、UDP)。 找回/恢复删除的文件
  • [样例] lsof -p $pid 查看对应进程关联打开的 网络、文件、设备、socket链接 等。如果要查看某个pid的TCP类型文件,执行lsof -p $pid | grep TCP 即可查看到监听的TCP网络及端口相关信息
  • [样例] lsof -i $port 查看对应端口的占用情况

mpstat

  • [简介] todo

vmstat

  • [简介] todo

cachestat

  • [简介] 缓存命中率
  • [样例] cachestat 1 3
  • [参数含义]
    • TOTAL ,表示总的 I/O 次数;
    • MISSES ,表示缓存未命中的次数;
    • HITS ,表示缓存命中的次数;
    • DIRTIES, 表示新增到缓存中的脏页数;
    • BUFFERS_MB 表示 Buffers 的大小,以 MB 为单位;
    • CACHED_MB 表示 Cache 的大小,以 MB 为单位

cachetop

  • [简介] 缓存命中率:输出跟 top 类似,默认按照缓存的命中次数(HITS)排序,展示了每个进程的缓存命中情况。具体到每一个指标,这里的 HITS、MISSES 和 DIRTIES ,跟 cachestat 里的含义一样,分别代表间隔时间内的缓存命中次数、未命中次数以及新增到缓存中的脏页数。
  • [样例] cachetop

slabtop

  • [简介] 实时显示内核slab内存缓存信息,使用 slabtop ,来找到占用内存最多的缓存类型。内核的模块在分配资源的时候,为了提高效率和资源的利用率,都是透过slab来分配的。通过slab的信息,再配合源码能粗粗了解系统的运行情况,比如说什么资源有没有不正常的多,或者什么资源有没有泄漏。linux系统透过/proc/slabinfo来向用户暴露slab的使用情况。Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。Jeff 的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff 发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针对特定目而初始化的状态。Linux slab 分配器使用了这种思想和其他一些思想来构建一个在空间和时间上都具有高效性的内存分配器。保存着监视系统中所有活动的 slab 缓存的信息的文件为/proc/slabinfo。
  • [样例] slabtop

strace

  • [简介] 跟进程系统调用的工具,观察对应pid进程的系统调用
  • [安装] apt install strace
  • [样例]: 运行 strace 命令,并用 -p 参数指定 PID 号 strace -p 6082

perf

  • [简介] todo
  • [安装] todo
  • [样例]: 采样操作系统函数调用 perf record -g,获取调用报告 perf report

pstree

  • [简介]
  • [样例] pstree -aps 3084; a 表示输出命令行选项 ; p 表 PID; s 表示指定进程的父进程

valgrind

  • [简介] 内存泄露检测工具,应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况

  • 内存检测王者之剑—valgrind

  • [简介]

系统测试

stress

  • [简介] cpu、io 压测测试

iperf

  • [简介] 网络性能测试

sysbench

  • [简介] sysbench是跨平台的基准测试工具

dd

  • [简介]Linux dd 命令用于读取、转换并输出数据。dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。
  • [使用场景]适用于测试磁盘的顺序读写场景
  • [样例] 生成一个 512MB 的临时文件 dd if=/dev/sda1 of=file bs=1M count=512
  • [样例] 写入指定目录文件夹路径文件 dd if=/dev/zero of=/Users/lewis/fx/test.file bs=1M count=10000K iflag=direct

fio

  • [简介]: 测试磁盘的 IOPS、吞吐量以及响应时间等核心指标

内核

procfs

  • [简介]: 在许多类 Unix 计算机系统中, procfs 是 进程 文件系统 (file system) 的缩写,包含一个伪文件系统(启动时动态生成的文件系统),用于通过内核访问进程信息。这个文件系统通常被挂载到 /proc 目录。由于 /proc 不是一个真正的文件系统,它也就不占用存储空间,只是占用有限的内存。

  • 执行命令 ls /etc/proc ,即可查阅系统进程的文件信息

  • 进程相关

    • 每个正在运行的进程对应于/proc下的一个目录,目录名就是进程的PID,每个目录包含:
    • /proc/PID/cmdline, 启动该进程的命令行.
    • /proc/PID/cwd, 当前工作目录的符号链接.
    • /proc/PID/environ 影响进程的环境变量的名字和值.
    • /proc/PID/exe, 最初的可执行文件的符号链接, 如果它还存在的话。
    • /proc/PID/fd, 一个目录,包含每个打开的文件描述符的符号链接.
    • /proc/PID/fdinfo, 一个目录,包含每个打开的文件描述符的位置和标记
    • /proc/PID/maps, 一个文本文件包含内存映射文件与块的信息。
    • /proc/PID/mem, 一个二进制图像(image)表示进程的虚拟内存, 只能通过ptrace化进程访问.
    • /proc/PID/root, 该进程所能看到的根路径的符号链接。如果没有chroot监狱,那么进程的根路径是/.
    • /proc/PID/status包含了进程的基本信息,包括运行状态、内存使用。
    • /proc/PID/task, 一个目录包含了硬链接到该进程启动的任何任务
  • 系统相关

    • /proc/softirqs 系统软中断
    • /proc/crypto, 可利用的加密模块列表
    • /proc/devices, 字符设备与块设备列表,按照设备ID排序,但给出了/dev名字的主要部分
    • /proc/diskstats, 给出了每一块逻辑磁盘设备的一些信息
    • /proc/filesystems, 当前时刻内核支持的文件系统的列表
    • /proc/interrupts, /proc/iomem, /proc/ioports, /proc/irq, 设备的一些与中断、内存访问有 - 关的信息
    • /proc/kmsg, 用于跟踪读取内核消息
    • /proc/meminfo, 包含内核管理内存的一些汇总信息
    • /proc/modules, 是/proc最重要的文件之一, 包含了当前加载的内核模块列表
    • /proc/mounts, 包含了当前安装设备及安装点的符号链接
    • /proc/net/, 一个目录包含了当前网络栈的信息,特别是/proc/net/nf_conntrack列出了存在的网络连 - 接(对跟踪路由特别有用,因为iptables转发被用于重定向网络连接)
    • /proc/partitions, 一个设备号、尺寸与/dev名的列表,内核用于辨别已存在的硬盘分区
    • /proc/scsi, 给出任何通过SCSI或RAID控制器挂接的设备的信息
    • /proc/self (即/proc/PID/其中进程ID是当前进程的) 为当前进程的符号链接
    • /proc/slabinfo, Linux内核频繁使用的对象的统计信息
    • /proc/swaps, 活动交换分区的信息,如尺寸、优先级等。
    • /proc/sys,动态可配置的内核选项. 其下的目录对应与内核区域,包含了可读与可写的虚拟文件 - (virtual file).
    • /proc/sysvipc, 包括共享内存与进程间通信 (IPC)信息
    • /proc/tty, 包含当前终端信息; /proc/tty/driver是可利用的tty类型列表,其中的每一个是该类型的 - 可用设备列表。
    • /proc/uptime, 内核启动后经过的秒数与idle模式的秒数
    • /proc/version, 包含Linux内核版本,发布号(distribution number), 编译内核的gcc版本,其他 - 相关的版本
    • /proc/{pid}/smaps,读取某个pid进程对应的虚拟内存区间到信息
    • 其他文件依赖于不同的硬件,模块配置与内核改变
    • /proc/sys/vm/swappiness,Linux 提供了一个 /proc/sys/vm/swappiness 选项,用来调整使用 Swap 的积极程度。swappiness 的范围是 0-100,数值越大,越积极使用 Swap,也就是更倾向于回收匿名页;数值越小,越消极使用 Swap,也就是更倾向于回收文件页。

网络

nslookup

  • [简介] 用于分析 DNS 的解析过程

dig

  • [简介] 用于分析 DNS 的解析过程

ping

  • [简介] 用于测试服务器延时

tcpdump

  • [简介] 用于网络抓包
  • [输出格式] 时间戳 协议 源地址. 源端口 > 目的地址. 目的端口 网络包详细信息
    tcpdump-选项
    tcpdump-表达式过滤