傳統運維學習OceanBase多少會因為不熟悉新事物有些擔心,然而換OceanBase就跟換一輛進階車一樣差別不會太多。由于大部分人還沒接觸過OceanBase,這裡介紹OceanBase運維還有點早。不如先分享一下如果要安裝OceanBase需要具備哪些經驗。對于老司機而言,下面的内容都會顯得很淺顯,可以直接拉到最後。
資料庫伺服器
對于主要使用
IOE
架構的企業,估計很少用普通商用伺服器去部署資料庫,是以
DBA
或者運維都很少去想一個資料庫伺服器要做哪些事情。是以當發現要把資料庫搬到普通伺服器上時,會有非常多的擔心。如性能行不行、可靠性高不高、怎麼做高可用、出事了誰擔責任。這種擔心也很正常,在早期阿裡巴巴DBA探索在普通伺服器上部署ORACLE時,也是内部争論很多,有很多擔心。從這篇舊文《ORACLE Fusion-io最佳實踐 http://www.hellodb.net/2011/02/oracle-fusion-io.html》可以看出。
選用商用伺服器後,性能主要取決于CPU和IO。這裡稍微深入的分析一下。
CPU
普通伺服器的
CPU
是
x86
架構架構.其單HZ處理能力已經超過IBM的Power序列。不過Power序列的記憶體通路使用
SMP
結構,所有CPU通路記憶體速度都一緻,
x86
伺服器通路記憶體采用
NUMA
結構,CPU和記憶體的節點一一對應,跨節點通路性能會有下降(有點分布式存儲的感覺),并且還有不同記憶體節點間同步成本。是以随着CPU增長,
x86
的線性增長能力可能不如
Power
序列。當然單純比較CPU意義也不大,還要綜合穩定性看。不過使用
x86
伺服器做資料庫伺服器,一個經驗就是關閉
NUMA
。
NUMA
關閉方法也很簡單,在
/etc/grub.conf
的
kernel
一行後添加了
numa=off
,重新開機伺服器就生效。是以,如果要準備OceanBase資料庫伺服器,也請先關閉
NUMA
。
此外對于
CPU
還有描述也需要了解一下。實體CPU指真實的CPU硬體,通常說的幾路就是指這個個數,Linux下用不同
Physical ID
區分。核心數(
Core
)是實體CPU的内部劃分。Intel的
CPU
支援超線程技術,每個
Core
可以變成兩個邏輯
CPU
。
# 檢視實體CPU個數
cat /proc/cpuinfo | grep 'physical id' |
sort
| uniq |wc -l
# 檢視核心個數
cat /proc/cpuinfo | grep 'core id' |
sort
| uniq |wc -l
# 檢視邏輯CPU個數
cat /proc/cpuinfo | grep 'processor' |
sort
|
wc -l
#lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 24
On-line CPU(s) list: 0-23
Thread(s) per core: 2
Core(s) per soc
ket: 6
Socket(s): 2
NUMA node(s): 1
......
日常交流中我們說的CPU個數多是指邏輯
CPU
個數。OceanBase程序啟動後,會擷取伺服器的邏輯
CPU
個數,扣除2個給OS,其他都聲稱是自己的。OceanBase的測試環境建議
CPU
個數不要低于32個。
記憶體
linux的記憶體頁大小是
4K
,如今記憶體都很大,256G也不算什麼,為了管理這麼多記憶體頁,OS的頁目錄也會非常大。是以Linux從核心2.6版本後支援一種大頁技術,頁大小為
2M
。後來
RHEL 6
又引入透明大頁技術,前者就叫傳統大頁技術。二者差別是傳統大頁管理是預配置設定、透明大頁管理是動态配置設定。使用透明大頁時,可能在配置設定失敗時核心會嘗試直接回收和壓縮其他記憶體導緻
sys
飙高,系統性能可能出現大幅抖動甚至重新開機。ORACLE的安裝文檔就建議使用傳統大頁,關閉透明大頁。OceanBase也是同理。
#線上關掉方法:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
存儲
存儲常常是資料庫的性能瓶頸,也是運維最大的擔憂。商用伺服器當然也支援連接配接FC存儲。不過如今這早已不是唯一選擇。如今使用SSD方案的IO性能已經可以遠遠超過存儲。SSD的類型很多,早期使用SSD的時候會有一個擦寫次數的限制(壽命問題)。資料庫IO通常有兩種類型特點,一是随機
IO
,一是順序
IO
。ORACLE資料庫的資料讀寫多是随機
IO
比較多,是以對
SSD
壽命有要求。OceanBase讀寫有随機
IO
,不過次數相對來說很少(因為OceanBase使用LSM模型,寫首先是盡可能的緩存在記憶體裡,不及時落盤)。此外就是密集的大IO,可能也有很多順序IO。總體來說OceanBase對
SSD
壽命非常友好。
SSD
的存儲流程是資料經過裝置實體接口,然後是邏輯協定轉換為指令協定。這其中實體接口有
SATA
、
PCIE
的差別,邏輯協定有
AHCI
和
NVME
之分。
NVME
相對于
AHCI
具有低延時、高
IOPS
、低功耗等。
實體接口 | 邏輯協定 | 指令協定 |
SATA | AHCI | ATA |
M.2/PCIe | AHCI | ATA |
PCIe/U2 | NVMe | NVMe |
就實際使用體驗而言,使用
SATA
接口的
SSD
,
IO
依然很可能是資料庫的性能瓶頸,而使用
PCIe
接口搭配
NVMe
協定的
SSD
時,資料庫性能瓶頸通常又轉移到
CPU
了。OceanBase生産環境如果業務對資料庫性能要求非常高,建議搭配适量的
NVMe
協定的
SSD
盤。
Linux作業系統
核心參數設定
Linux的核心參數在
/etc/sysctl.conf
裡修改。通常資料庫軟體的原理都會内部使用多線程,使用信号量,并且大量讀寫檔案和網絡裝置(本質上也是檔案)。是以ORACLE資料庫的安裝裡會建議調整相關核心參數,OceanBase也是如此。這些參數都是共性。
vi /etc/sysctl.conf
# for database
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 10000
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.ip_local_port_range = 3500 65535
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_slow_start_after_idle=0
vm.swappiness = 0
kernel.core_pattern = /data/1/core-%e-%p-%t
vm.min_free_kbytes = 2097152
生效指令
sysctl -p
Shell資源限制設定
資料庫軟體啟動時也是在某個
Shell
會話下,而Linux預設會限制一個會話打開的資源。如檔案句柄數、棧大小等等。這些預設值并不滿足資料庫軟體的需求。也需要修改。
vi /etc/security/limits.conf
* soft nofile 655350
* hard nofile 655350
* soft stack 20480
* hard stack 20480
* soft nproc 655360
* hard nproc 655360
* soft core unlimited
* hard core unlimited
修改完後要退出目前會話再次登入驗證
admin$ulimit -a
$ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 385847
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 655360
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 20480
cpu time (seconds, -t) unlimited
max user processes (-u) 655360
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
安全和防火牆設定
SELinux是Linux的一個本機安全性授權,預設設定對程序通路權限限制很多。想用好SELinux非常麻煩,資料庫軟體通常都建議直接關閉這個服務。
線上關閉(其實是設定為Permissive)
#指令行下關閉
#setenforce 0
#getenforce
Permissive
永久關閉,修改配置檔案,并重新開機。
vi /etc/selinux/config
SELINUX=disabled
注意這個檔案千萬不要改錯,否則重新開機後OS會啟動失敗。需要進入單使用者模式修複。
Linux預設安裝會啟動防火牆,而資料庫通常都會有一些監聽端口響應使用者請求。分布式資料庫節點之間也會有通信需求。需要開通相關端口的通路權限。不過大企業運維裡,一一去設定伺服器的防火牆非常麻煩,一旦設定錯誤排查定位也不容易,是以都選擇直接關閉。伺服器的通路安全通過網絡在
VLAN
級别設定端口通路的白名單和黑名單來保證。
#清理防火牆規則
#iptables -F
#檢視防火牆規則
#iptables -nvL
#停用防火牆服務
#systemctl stop filrewalld
#禁用防火牆服務(防止重新開機後啟動)
#systemctl disable firewalld
時間同步
資料庫伺服器的時間和應用伺服器的時間,以及使用者生活中的時間應保持同步。企業生産環境都有專用的時間同步伺服器(又叫
NTP
伺服器)。運維需要能排查伺服器跟
NTP
源的時間差異。
#配置ntp源
vi /etc/ntp.conf
#添加
server 110.75.186.247 iburst minpoll 8 maxpoll 10
#檢視同步誤差
#ntpq -4p
#檢視目前同步進度
$ntpstat
synchronised to NTP server (100.***.3.1) at stratum 3
time correct to within 6 ms
polling server every 64 s
不過對于叢集資料庫而言,還要看節點之間的時間同步誤差。理論上大家都跟
NTP
保持同步的話,各個節點之間的時間誤差未必很大。
$clockdiff 100.***.152.81
.
host=100.***.152.81 rtt=750(187)ms/0ms delta=0ms/0ms Sat Jul 6 10:08:25 2019
在很多企業的線下環境裡,都沒有專用的
NTP
伺服器,當需要時間同步時,可以挑選一台性能相對好的伺服器做
NTP
伺服器
# yum -y install ntpd
# vi /etc/ntp.conf
#删除所有行
#注釋restrict default ignore
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10 # 跟本地硬體同步
#當然,我們也可以添加server xxx.xxx.xxx.xxx,讓他和其他的time server時間同步。
各個機器配置
server
後位址為
NTP
源即可。第一次如果通過
clockdiff
發現跟
NTP
源時間差異很大,可以先用
ntpdate -u NTP源IP
強制同步時間。注意手動同步可能跟自動同步會有沖突:
1 Sep 20:09:19 ntpdate[2614]: the NTP socket is in use, exiting
。這個避開同時運作即可。
然後重新開機 ntpd服務
#systemctl restart ntpd
NTP
同步有個特點,一旦時間相差很大時,同步的時候會一點點縮小差距,目地是為了避免時間跳動範圍太大。對于OceanBase叢集資料庫而言,各個節點的時間誤差必須保證在
100ms
以内(否則叢集的核心選舉服務會異常),
50ms
以内比較保險,
10ms
以内最佳。如果
NTP
自動同步服務依然不能保證各個節點時間誤差在要求以内,那可以用
crontab
每分鐘定時同步。快速恢複叢集的穩定性比什麼都重要。
#crontab -e
* * * * * /sbin/ntpdate -u 100.***.152.81 >> /tmp/ntpdate.log 2>&1
使用者設定
建立使用者是最簡單的操作,用
useradd
指令即可。不過很少有人會指定使用者的
uid
和
gid
。這裡就提一下,可能在某些情況下涉及到目錄的共享時,雖然都是同一個使用者但是由于各自的
uid
以及
gid
不同導緻有權限問題。
# groupadd -g 500 admin
# useradd -u 500 -g 500 admin
# groupmod -g 500 admin
# usermod -u 500 -g 500 admin
檔案系統設定
所有的關系型資料庫都有事務日志(通常說的
Redo
),日志的寫
IO
特點是順序
IO
,資料檔案的寫
IO
特點多是随機
IO
。為了性能考慮,最佳實踐通常都是建議存放資料檔案和事務日志檔案的裝置檔案彼此獨立,這樣減少彼此的争用。通常性能最好的磁盤會存放事務日志(日志寫可能是資料庫性能的瓶頸)。
這裡有很多種做法。
如果機器盤很多,那麼建議2塊盤做
RAID 1
給OS用,其他的盤分為兩部分,分别做
RAID 10
或
RAID 5
,輸出兩塊實體裝置,然後分别格式化為檔案系統。
如果機器盤不多時,分開可能難以兼顧OS、資料和日志的空間或性能需求。則可以用
LVM
将多塊盤(
PV
)聚合在一起,然後劃分出不同的邏輯裝置(
LV
),然後再針對性格式化為檔案系統,提供給資料和日志使用。
LVM
是卷管理軟體,對管理磁盤非常友善,将實體層和業務層徹底隔離,可以很友善給
LV
擴容和縮容(而
fdisk
分區軟體則有擴容不友善問題)。Linux在預設安裝的時候,常用LVM管理磁盤。運維需要詳細看看分區内容是否合理。特别是作為資料庫伺服器,手動使用
LVM
管理極為重要,一定要盡可能的保證資料目錄和日志目錄使用的裝置盡可能的獨立。
還有一種情形,伺服器隻有兩塊盤,這個時候還要做
RAID
最後隻能輸出一塊裝置。這時候不管怎麼管理劃分,在底層資料檔案和日志檔案都是共用一個實體裝置。除非這個盤是NVME協定的SSD大盤,否則實際性能并不很好。這樣的伺服器,也并不适合做資料庫伺服器用。
總結: 以上要求可以作為資料庫主機的通用安裝模闆.
Docker技術
以前安裝資料庫都是DBA手動一步一步安裝,資料庫廠商也寫了很詳盡的安裝文檔,在安裝的過程中學習。當大量資料庫使用普通伺服器時(指的是MySQL),DBA一台台手動安裝可能就比較麻煩,還容易出錯。除了作業系統安裝自動化配置安裝模闆外,還有就是用Docker部署。
對于要安裝的應用或資料庫,首先制作一個docker鏡像,将基本的配置、軟體包都包含進去,然後寫編排任務,在啟動docker以後動态的根據配置傳遞不同的啟動參數和執行一些固定的自定義初始化操作。Docker需要掌握一些基本的指令。
首先建議給docker準備一個專用的檔案系統用于存放鏡像檔案,目錄名:
/docker
。
其次就是安裝docker
# 安裝docker軟體
# yum -y install docker
#啟動docker服務
# systemctl start docker
然後就是加載鏡像、檢視和運維docker。
# 加載鏡像
# docker load -i ocp2.tar.gz
# 檢視鏡像
# docker images
# 檢視運作的docker
# docker ps
# 檢視所有的docker(包括已停止的)
# docker ps -a
# 啟動/停止/重新開機 某個 docker
# docker start/stop/restart xxxxx(docker辨別或名稱)
# 删除 docker
# docker rm xxx
# 删除鏡像
# docker rmi xxx
# 檢視docker運作日志
# docker logs xxx
# 進入docker
# docker exec -it xxxxx(docker辨別或名稱) bash
# 向docker複制檔案
# docker cp filexxx.gz xxxx:~/ # xxxx是docker辨別或名稱
OceanBase的安裝支援手動安裝方式和自動安裝,自動安裝是通過
OCP
平台做的。
OCP
的安裝是使用
Antman
産品(原理是Docker)部署,要求有三台實體機。會在每台機器上起3個Docker,分别是
OCP
,
OBProxy
和
OB
。這個
OB
是
OCP
的中繼資料庫,是運維最重要的資料庫,是以建議機器配置不要低于業務資料庫主機要求。
運維問題定位
如果問題有明确的報錯資訊,則根據報錯資訊定位。
比如說報不能打開檔案之類,實際上有成功的也有失敗的,則看使用者的
ulimit
設定裡參數是否合理。如果是沒有權限打開檔案,則看檔案所在目錄的owner,程序
owner
是否正确。如果問題是程序異常退出,則看系統日志
/var/log/messages
裡是否有OOM之類報錯。
如果OB資料庫基本的SQL都報逾時錯誤,則先看OB叢集的多個節點之前的時間是否同步,NTP伺服器是否正常等。
性能問題
有時候主機會表現出性能下降,進而導緻資料庫出現異常。二者之間的聯系并不一定表現的很直接。是以在碰到問題的時候,可以順便快速的看看主機的性能是否正常。通常隻需要看CPU、記憶體、磁盤、網絡就行。這裡直接推薦用一個指令(
tsar
)就可以看所有的。
- CPU性能
CPU用
top
指令也可以看。原理相同。通常情況下,資料庫很忙的時候,
load
會偏高、
user
使用率會相對比較高。再從
top
指令裡看是哪個程序。如果是資料庫程序,那基本确認是資料庫内部性能問題。如果
sys
使用率也相對比較高(如超過
20
),則留意OS的異常。如果
wait
使用率相對比較高,則看看
IO
的性能。
load
的結果裡
load1
,
load5
,
load15
分别代表1分鐘内,5分鐘内,15分鐘内平均值。可以看出
load
變化趨勢。
$tsar --cpu --load -l -i 3
Time -----------------------cpu---------------------- -------------------load-----------------
Time user sys wait hirq sirq util load1 load5 load15 runq plit
07/07/19-15:24:54 25.59 10.62 3.08 0.00 0.42 36.63 13.78 12.99 12.15 5.00 2.8K
07/07/19-15:24:57 25.42 10.63 7.10 0.00 0.42 36.46 13.72 12.99 12.15 10.00 2.8K
07/07/19-15:25:00 25.25 10.11 3.85 0.00 0.40 35.77 13.58 12.97 12.15 3.00 2.8K
07/07/19-15:25:03 29.34 11.31 4.89 0.00 0.48 41.13 13.58 12.97 12.15 7.00 2.8K
07/07/19-15:25:06 24.80 9.93 5.92 0.00 0.36 35.09 13.37 12.94 12.14 25.00 2.8K
^C
- MEM性能
Memory主要是關注
free
、
buffer
、
cache
的變化是否正常。通常運作一段時間後資料庫主機的記憶體分布就比較固定了。如有異常變化,還需要結合其他資訊判斷。
#tsar --mem -l -i 3
Time -----------------------mem----------------------
Time free used buff cach total util
07/07/19-15:31:46 3.0G 31.2G 1.8G 58.2G 94.2G 33.16
07/07/19-15:31:49 3.0G 31.2G 1.8G 58.2G 94.2G 33.13
07/07/19-15:31:52 3.0G 31.2G 1.8G 58.2G 94.2G 33.15
07/07/19-15:31:55 3.0G 31.2G 1.8G 58.2G 94.2G 33.15
^C
- IO性能
看IO性能首先要确認目前的磁盤分區、檔案系統設定等。通過
fdisk
、
mount
和
df -h
指令檢視。找到資料庫資料和檔案所在的磁盤,使用
tsar
觀察
IO
性能。對于一個磁盤的吞吐能力,響應時間水準應該事先有所了解。
#ll /dev/mapper/ob_vg-ob_data
lrwxrwxrwx 1 root root 7 Jun 12 15:28 /dev/mapper/ob_vg-ob_data -> ../dm-1
#ll /dev/mapper/ob_vg-ob_log
lrwxrwxrwx 1 root root 7 Jun 12 15:28 /dev/mapper/ob_vg-ob_log -> ../dm-0
#tsar --io -I dm-0 -l -i 3
Time ------------------------------------------dm-0------------------------------------------
Time rrqms wrqms rs ws rsecs wsecs rqsize qusize await svctm util
07/07/19-15:38:09 0.00 0.00 0.00 251.67 0.00 5.3K 21.67 2.00 8.89 3.97 99.87
07/07/19-15:38:12 0.00 0.00 0.00 231.67 0.00 4.7K 20.85 2.00 9.08 3.95 91.50
07/07/19-15:38:15 0.00 0.00 0.00 227.33 0.00 1.7K 7.73 1.00 8.71 4.39 99.73
07/07/19-15:38:18 0.00 0.00 0.00 213.33 0.00 1.3K 6.36 1.00 8.31 4.31 92.00
07/07/19-15:38:21 0.00 0.00 0.00 202.33 0.00 1.1K 5.54 1.00 9.09 4.51 91.20
07/07/19-15:38:24 0.00 0.00 0.00 230.67 0.00 1.3K 5.57 1.00 8.34 4.32 99.73
07/07/19-15:38:27 0.00 0.00 0.00 203.33 0.00 1.1K 5.65 1.00 8.65 4.49 91.27
07/07/19-15:38:30 0.00 0.00 0.00 224.67 0.00 1.5K 6.84 1.00 8.34 4.43 99.47
07/07/19-15:38:33 0.00 0.00 0.00 232.33 0.00 3.0K 13.11 2.00 8.61 3.96 92.07
07/07/19-15:38:36 0.00 0.00 0.00 210.67 0.00 1.2K 5.80 1.00 8.27 4.36 91.87
07/07/19-15:38:39 0.00 0.00 0.00 227.33 0.00 1.3K 5.75 1.00 8.16 4.39 99.90
^C
其中
IO Util
是個比較複雜的參數。如果是機械盤,這個
Util
可以反映出磁盤的繁忙程度,
svctm
會在幾毫秒以上。如果是
SSD
盤,
svctm
會在零點幾毫秒。關于使用率有個近似公式:
使用率U = 吞吐量 * 每次平均服務時間
. 是以SSD盤需要看響應時間(
svctm
)、等待時間(
await
)等資訊綜合判斷是否到瓶頸。
- 網絡
首先通過
ethtool
指令檢視網卡的速度。然後通過
tsar
指令看網卡實際上傳下載下傳速度以及丢包率。如果接近或者超過網卡的能力,則表示網卡此刻接近吞吐量瓶頸。
#ethtool bond0
Settings for bond0:
Supported ports: [ ]
Supported link modes: Not reported
Supported pause frame use: No
Supports auto-negotiation: No
Advertised link modes: Not reported
Advertised pause frame use: No
Advertised auto-negotiation: No
Speed: 2000Mb/s
Duplex: Full
Port: Other
PHYAD: 0
Transceiver: internal
Auto-negotiation: off
Link detected: yes
#tsar --traffic -l -i 3
Time ---------------------traffic--------------------
Time bytin bytout pktin pktout pkterr pktdrp
07/07/19-15:58:24 8.7M 2.3M 9.9K 6.1K 0.00 0.00
07/07/19-15:58:27 9.0M 2.6M 10.0K 6.2K 0.00 0.00
07/07/19-15:58:30 9.7M 2.7M 10.7K 6.5K 0.00 0.00
07/07/19-15:58:33 10.7M 2.6M 11.0K 6.1K 0.00 0.00
07/07/19-15:58:36 8.5M 2.2M 9.5K 5.7K 0.00 0.00
^C
備注:
主機的性能是最容易看最基礎的,如果主機在某方面呈現性能瓶頸,資料庫的性能和穩定性很可能會受影響。二者之間的聯系并不會表現的很直接,需要多觀察總結成經驗。tsar 更多用法參見《推薦一款淘寶開源的主機性能采集軟體——tsar》。
總結
以上大部分說的是用普通伺服器作為資料庫伺服器的一些運維經驗。傳統業務轉型到分布式資料庫架構後,普通伺服器的規模和運維工作量會增加,是以一些基礎的資料庫主機安裝模闆、運維規範以及自動化運維都會應運而生。然而自動化運維産品不是智能化産品,當環境不标準或者異常時,其機制就可能失效,就需要運維介入處理。掌握一些基礎的技能是資料庫運維安全駕駛的前提。