注册
基础优化——服务器篇
专栏/小时的百草园/ 文章详情 /

基础优化——服务器篇

Joker￿ 2021/06/16 3229 10 0
摘要 本文从 CPU、内存、磁盘以及操作系统四个方面介绍了服务器的优化,以保证数据库软件能在服务器上更好的运行。

在项目实施落地过程中,一定会经过一系列的优化调整过程,这个过程中涵盖了方方面面的优化,下面我将之前记录的一些细节以及注意事项列举出来,供大家参考。

我们知道服务器硬件是数据库软件运行的基础,IT 行业发展到今天,想要知道软件的瓶颈,一定要确保您的硬件基础不再是您的短板,这样来评价软件的性能才有意义。

为什么同样的服务器环境,别人用得比你顺手,别人就很少出问题呢?下面,我们简单来分析原因

1、CPU

CPU 的哪些因素会影响数据库的运行呢?

我们首先来看一下服务器的 CPU 信息

2.1.png

从 lscpu 中,我们可以得到以下信息
架构:X86_64
核数(CPUs):80 核
numa 节点:2
基础频率:2.5GHz
超频频率:3199.920
最大睿频:3900
L2缓存:1M
L3缓存:27.5M

得到这些信息之后,我们应该关注些什么?

1.1 架构

目前主流的 CPU 架构是 x86 和 ARM,比较有代表性的就是 Intel,ARM,鲲鹏、飞腾和龙芯平台了。不同架构下的 CPU 有不同的特点,需要注意的是在 x86 平台中,CPU 可以超频,这一项优势会极大的提升 CPU 计算性能。

1.2 主频率

CPU 的主频率直接决定了计算速度。

同样的一次全表扫描或者关联计算,在不考虑其他变量因素的情况下,主频率越高,执行的速度就越快。就像 BTC 挖矿一样,显卡越好挖矿越快。

1.3 核数

在不开启并行的前提下,单个任务线程或者单个会话查询,最多只能使用一个核的算力。可以在 TOP 界面中清晰地看到 CPU 使用率:

2.2.png

需要注意的是,在多核 CPU 中该值可以达到(核数 *100)%,所以在关注资源使用率时,不要盲目的认为进程对 CPU 使用率很高就是软件不行,还要考虑系统的负载情况。

如果在进行压力测试或者并发量极高,使用更多的 CPU 资源才是上上之选。测试高并发时可以关注负载情况,在某些场景下,可以考虑使用限流来减缓 CPU 的压力

1.4 缓存

我们知道在服务器中,速度是 CPU > 缓存 > 内存 > 磁盘。

数据库在计算时,CPU 需要的数据,都是先从磁盘读到内存,再将即将访问的数据放在 cache 中。CPU 总是优先访问 cache 中的数据,因此提升缓存的容量和速度是必要的。

1.5 NUMA 节点

一个 CPU 可能对应着多个内存插槽,CPU 访问不同类型节点内存的速度是不相同的,访问本地节点的速度最快,访问远端节点的速度最慢,为了提升性能,减少跨节点访问的 NUMA 模型诞生了,在启用 NUMA 时,CPU 访问数据会使用本地节点的内存优先分配。

然而在数据库服务器中,数据库进程管理的数据通常是需要跨节点访问的,单个节点可能没有足够的内存存放数据。这样就可能会造成一些问题,例如还有别的节点富余内存空闲情况下,一个 NUMA 节点的所有内存分配完了之后,CPU 再要数据时,可能会优先分配 SWAP 来使用。

因此我们在数据库服务器中,通常是需要关闭 NUMA 的。

2、内存

在上一节的内容中,我们已经讲过 NUMA 节点和内存访问的关系,这里我们主要分析下达梦数据库的内存结构,以及在实际使用过程中,内存是如何影响数据库软件性能的。

首先我们要了解达梦数据库内存中存了什么?
达梦数据库的内存管理,可以分为三大部分:缓冲区(BUFFER)、内存池(MEMORY_POOL)和其他内存区。

2.1 缓冲区

数据缓冲区

数据缓冲区是从磁盘中读取的数据页在内存中的镜像,对应 dm.ini 参数中的 BUFFER、FAST_POOL、RECYCLE 和 KEEP 等。

普通数据页的缓存淘汰策略为 LRU 算法(Least recently used,最近最少使用),算法根据数据的历史访问记录来淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

每条 SQL 语句请求的数据,都是从数据缓冲区中取得的,如果缓冲区没有该数据,才会从磁盘中读取数据并加载到缓冲区中。

字典缓存区

字典缓冲区是保存数据库对象的一片缓冲区,对应的 INI 参数是 DICT_CACHE_SIZE。

DM7 中数据对象对应的是系统表上的信息,而内存中的数据对象则是通过解析系统表上的信息得到的。字典缓冲区的存在既能避免频繁向磁盘请求获取系统表信息,也可以减少系统表信息解析开销,在数据对象较多的情况下建议适当调大 DICT_CACHE_SIZE 参数。

字典缓冲区的缓存淘汰策略同样是 LRU 算法,可以通过视图 v$db_cache查看:

2.3.png

当 SIZE_LRU_DISCARD 不为 0 时,需要调整 dm.ini 中 DICT_BUF_SIZE 的大小。

SQL 缓冲区

SQL 缓冲区是用来存储包信息(PACKAGE)、执行计划和结果集缓存的一片专用缓存区域,简称 SCP(SQL CACHE POOL),对应的 INI 参数是CACHE_POOL_SIZE。

对于 SQL 类别比较多,或者 PKG 文件比较多的系统,建议将该参数调大。

日志缓冲区

日志缓冲区对应 INI 参数中的 RLOG_BUF_SIZE,数据库日志将对磁盘的随机写转换成顺序写。

2.2 内存池

内存池是服务器启动时从操作系统申请的一大片内存,后续服务器运行过程中,很多需要内存分配的地方都是从内存池分配。

如果需要的内存大于配置值(MEMORY_POOL),内存池会自动扩展,最大扩展到 MAX_OS_MEMORY 大小,一般情况下不收缩。

可以通过 v$mem_pool 视图查看内存的使用情况:

2.4.png

达梦数据库的内存配置参数有几个需要注意的地方,如果设置的不好,非常容易出现 OOM(Out Of Memory) 或者性能表现不佳。

  • MAX_OS_MEMORY
    这个参数限制了 dmserver 进程从操作系统中申请的最大内存百分比,计算时需要考虑物理内存和 SWAP 的总大小

  • MEMORY_TARGET
    当共享内存值扩充到该值的设置大小后,开始考虑回收空闲内存,配合 MAX_OS_MEMORY 使用,可以有效防止系统出现 OOM。
    当出现 OOM 时,需要在操作系统的日志(/var/log/messages)中查找相关信息,合理规划 dmserver 进程使用的内存。

  • MEMORY_POOL 和 MEMORY_N_POOLS
    共享内存池大小和共享内存分片。共享内存池会自动扩充,合理分片可以在高并发访问时有效的减少临界区冲突,提高性能。

2.3 其他内存区

服务器运行过程中,内存的使用有两种模式,一种是直接从内存池申请需要的内存大小,另外一种方式是从操作系统申请一大片内存作为自己模块的内存池来使用(VM_POOL、SESS_POOL 、RT_HEAP 等等)。

第二张模式可以减少频繁从数据库主内存池申请内存的开销,一般来说一个会话可以理解为一个单独的运行环境,有自己的私有内存池(HASH SORT 等操作都是从自己的私有池上申请内存,部分少量的从主池申请),部分线程或者子系统也拥有自己独立的内存池,如 CKPT 刷盘线程有 CKPT_POOL,序列管理有 NSEQ_POOL 内存池。
关于 SESS POOL 的使用可以参考这篇文章:《DM8 压力测试笔记》

3、磁盘

所有数据最终还是要存储到磁盘中,因此磁盘的读写速度决定了入库的性能。

3.1 测试磁盘读写速度

$ dd if=/dev/zero of=/dbdata/dmdata/test bs=32k count=20k oflag=dsync

3.2 磁盘调度

不同类型的存储,使用不同的调度算法

  • SSD 固态硬盘:NOOP 调度
  • SAS 机械盘:DEADLINE 调度

Linux 系统一般默认使用 CFQ 调度,修改磁盘调度的操作:
查看调度:cat /sys/block/sda/queue/scheduler
临时修改:echo “deadline” > /sys/block/sda/queue/scheduler
永久修改: grubby --update-kernel=ALL --args=“elevator=deadline”

4、操作系统

在 Linux 系统中,我们尤其需要注意的是用户和进程限制。

建议在使用达梦数据库时,使用专用的用户进行管理,既能控制权限,也能控制用户的资源使用限制;在启动进程之前,一定要检查 ulimit -a 是否能够满足使用需求,例如文件句柄数和最大线程数,这些都会影响使用过程中的体验。

5、总结

以上都是会对数据库性能产生非常大的影响的配置,希望大家在看过这篇文章后,能提前检查服务器的这些配置,越细心就越省心。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服