暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

OceanBase参数配置建议(一)

数据库技术闲谈 2019-08-19
762


OceanBase是一个通用的分布式关系型数据库,为适应不同客户场景,OceanBase支持配置不同参数。本文介绍一批参数的配置建议供参考。
此前在文章《从ORACLE/MySQL到OceanBase:参数或变量》里介绍过OceanBase支持集群参数和租户变量两种配置方法,本文就不再重复。对于参数的原理在以前的文章里提到过的这里也不再赘述。

启动参数


如果是手动搭建OceanBase集群时,需要指定启动参数,用于分配主机资源和指定总控服务。涉及到磁盘的启动参数,一旦指定就不能再改。如果是由OCP自动化安装的OB集群,这些参数都会设置的。可以事后查看。其他参数同理。
参数名参数描述默认值建议值分析
memory_limitOBServer能使用的物理内存,默认为0表示使用全部物理机内存的一个比例(默认80%)0
当单机起多个OBServer的时候,多个OBServer的使用内存之和要小于物理机总内存的90%
memory_limit_percentageOBServer使用物理机内存的比例,默认值80(表示80%),范围是[10,90)80
当单机起多个OBServer的时候,多个OBServer的使用内存之和要小于物理机总内存的90%
datafile_sizeOBServer实例的数据文件(block_file)大小0
当数据文件和日志文件共用一个文件系统目录时,需要先预留日志文件的空间(日志文件需要空间在内存3-4倍左右)。
datafile_disk_percentageOBServer实例的数据文件(block_file)大小占所在文件系统目录的比例0
当数据文件和日志文件共用一个文件系统目录时,需要先预留日志文件的空间(日志文件需要空间在内存3-4倍左右)。
config_additional_dirconfig配置文件的冗余目录

config配置文件默认在/home/admin/etc/下,为了避免丢失,建议再配置两个独立文件系统的目录,以分号隔开。
rootservice_list总控服务的成员列表

如果手动安装OB,需要指定这个总控服务成员列表,一般就是集群最早的三个节点。格式:192.168.0.100:2882:2881;192.168.0.101:2882:2881;192.168.0.103:2882:2881
obconfig_url获取总控服务地址的WEB API

如果有OCP安装,OCP会提供API并自动设置这个参数为OCP的API,格式是:http://11.***.***.83:8088/services?Action=ObRootServiceInfo&ObRegion=obdemo
 。如果没有OCP安装,可以手动模拟一个WEB API,在启动的时候指定这个API,格式是:http://11.***.***.83:8080/oceanbase_obconfig/obdemo
 。或者先用rootservice_list启动集群成功,后再指定这个参数也行。





问题诊断相关参数


OceanBase的问题诊断有多个途径,一是查看SQL性能相关视图,二是查看数据库运行日志。这里主要是设置运行日志的行为。
参数名参数描述默认值建议值分析
max_syslog_file_count设置observer.log.*
observer.wf.log.*
的文件个数。

100如果为0,则不自动删除observer.log
,每个log最大256MB,然后滚动生成。有可能会把所在文件系统目录空间打满,所以建议还是设置。
enable_syslog_recycle设置observer.log.*
observer.wf.log.*
循环利用。个数由参数max_syslog_file_count确定
false
跟参数max_syslog_file_count搭配使用。如果没有OCP,建议设置为true;否则,建议为False。OCP会自动清理运行日志。
syslog_level设置运行日志的日志level,有DEBUG,TRACE,INFO,WARN,USER_ERROR,ERROR六个级别INFO
OBServer运行日志生成量很大,结合所在目录空间大小和实际问题严重程度设置。目前客户还不大可能通过运行日志直接定位到原因,通常是把相关运行日志发送给OB支持人员定位。所以当有问题时,需要尽可能多的保留运行日志。
trace_log_slow_query_watermark在OBServer运行日志里打印执行时间超过这个值的SQL运行信息。2s
根据实际SQL排查需要指定。不要设置的太小,否则运行日志会打印很多慢查SQL。从最大时间往下逐步设置观察。定位方法:fgrep '[slow query]' observer.log.*
 。
enable_sql_audit开启或关闭SQL审计功能。True
内部视图gv$sql_audit
会记录所有租户的SQL运行日志。视图的内容是保存在内存里,内存大小有参数sql_audit_memory_limit
限制,记录数大小有参数sql_audit_queue_size
限制。当捕获到问题SQL后,为防止视图内容被后续SQL覆盖,可以临时关闭这个参数。
sql_audit_memory_limitSQL审计视图gv$sql_audit
所占用的最大内存大小。
3G10G如果QPS非常高,并且OBServer内存富余的情况下,可以调大这个参数到10G。
sql_audit_queue_sizeSQL审计视图gv$sql_audit
的记录数最大大小。
10000000
如果QPS非常高,可以调大这个参数。





冻结合并转储限速相关参数


OceanBase读写的特点是写操作都是在内存里记录增量变化,会消耗增量内存。如果增量内存消耗过快,可能有无法写入风险,报错:No memory or over tenant memory
错误等。所以针对不同的写入压力,需要调整冻结合并转储限速相关参数。
参数名参数描述默认值建议值分析
memstore_limit_percentagememstore增量内存占OBServer的内存比例。50
增量内存是OBServer内存使用的大户,可以在小范围内调整这个比例。
freeze_trigger_percentagememstore内存已使用比例超过这个阈值时会触发minor freeze
事件和转储事件。
70
如果写入压力很大,对内存消耗速度很快的话,需要降低这个阈值,已尽可能的触发转储释放内存。转储对资源消耗不大,对性能影响很小。
minor_freeze_timesOBServer发起minor freeze
事件的次数上限,超过这个阈值后,就会用major freeze
代替minor freeze
,然后这个minor freeze
使用次数又从0开始。
10100如果写入压力很大,对内存消耗速度很快的话,需要提高这个阈值,已尽可能推迟major freeze
的发生到业务低峰期。后者会触发合并,释放内存,会耗费OBServer一定资源。
enable_merge_by_turnOBServer合并时是否按Zone依次发起合并。如果不是,则所有Zone同时发起合并。False
合并对性能有一定影响,轮转(依次)合并可以降低这个影响范围,不过轮转期间会发起分区切主,分区上当时如果有大事务会出现中断回滚。
major_freeze_duty_timeOBServer每天默认触发major freeze
事件即合并的时间。
02:00
建议设置在业务低峰期。
write_throttling_maximum_durationOBServer限速目标,预估限速后增量内存还可以持续写入的时间。
30m这个根据实际写入对内存消耗速度和转储释放内存速度综合确定。
write_throttling_trigger_percentage当增量内存已使用比例到达这个阈值后,即刻开启限速逻辑。
85这个根据实际写入对内存消耗速度和转储释放内存速度综合确定。设置的太低,限速太早;设置的太高,限速太晚。





在后续的版本,估计要支持按租户发起合并的逻辑,会有更多参数推出。

性能调优参数


性能调优是根据场景来的,不同场景下参数取值可能会不同。没有一种参数组合可以解决所有问题。
下面描述一个大事务高并发场景。里面有些隐含参数(以_
开头的参数)。
参数名参数描述默认值建议值分析
large_query_thresholdOBServer的大查询执行时间标准。
10sSQL执行时间超过这个值(ms)就被判定为大查询,会使用单独的执行队列。为了避免个别大查询长期占用SQL执行队列导致小而块的查询饿死,OBServer设计了单独的大查询执行队列。根据实际SQL平均执行时间确定。
large_query_worker_percentageOBServer大查询执行队列的cpu worker线程数量比例30
如果期望大查询尽可能被满足,可以调高这个比例;反之调低这个比例。
enable_sql_operator_dump允许SQL层的排序/hash连接/窗口函数等中间结果dump到磁盘。TrueTrue
__temporary_file_io_area_size隐含参数,SQL中间结果写入到磁盘上文件大小限制。'20G'

_ob_clog_timeout_to_force_switch_leader当clog同步被阻塞的时候,等待时间超过阈值后就回收leader。
0s设置0s就无限等待。
_ob_replay_memory_limitclog回放时最多使用的内存。'500M''10G'
_ob_clog_disk_buffer_cntclog disk buffer cnt. Range: [1, 4000]
1024clog内部参数,减少内存争抢的概率。
_ob_btree_retire_limitthe retire station batch limit. Range: [16,65536]
2048clog内部参数,减少内存释放时发生锁等待的概率。
_ob_stat_refresh_timeoutthe time to refresh stat cache before it is terminated. Range: [1ms,+∞)
'100s'减少内部刷新发生超时的概率。
memory_chunk_cache_sizethe maximum size of memory cached by memory chunk cache. Range: [32M,]
'300G'减少OS回收OB内存的概率。
election_blacklist_intervalIf leader_revoke, this replica cannot be elected to leader in election_blacklist_intervalThe default value is 1800s. Range:[0s, 24h]18000
_ob_trans_rpc_timeouttransaction rpc timeout(s).transaction rpc timeout(s). Range: [0s, 3600s]
'10s'调大节点间RPC请求超时时间,减少RPC超时事件。
enable_auto_leader_switchspecifies whether partition leadership auto-switch is turned on. Value: True:turned on; False: turned offTrueFalse是否开启自动切主,影响负载均衡策略,不影响高可用。当分区分布均衡后就关闭这个参数,避免压测过程中发生负载均衡事件(会有分区迁移和切主)。
rpc_connect_error_retry_timesretry times if rpc connect error, to be removed010调大节点间RPC超时后的重试次数。





此外需要设置租户的变量
set @@global.ob_sql_work_area_percentage = 30;  -- 定义租户的SQL层可使用的内存空间占比
set @@global.parallel_max_servers=900; -- 提高px可同时并发的线程数上限
set @@global.parallel_servers_target=900; -- 提高px并行度

set @@global.recyclebin='OFF'; -- 关闭回收站

负载均衡参数


OceanBase的负载均衡原理是调整Leader副本的分布间接改变各个节点的负载。详情参见《揭秘OceanBase的弹性伸缩和负载均衡原理》。
通常建议当初始化很多表和数据后,可以开启负载均衡。对于业务上有密切联系的多个表,可以设置到同一个表分组下。当分区数量发生大的变化或者节点数量发生大的变化后可能会因为负载均衡调整现有分区的分布,会伴随着分区迁移和切换等。因此特殊场景下可以考虑关闭负载均衡机制。同时对于分区迁移的力度也要根据实际情形进行控制。

参数名参数描述默认值建议值分析
enable_rebalance是否开启负载均衡机制。True
根据实际情况考虑。
enable_auto_leader_switch是否自动切主。True
如果关闭,则负载均衡机制也不会生效。
data_copy_concurrencyOB集群里并行数据复制任务最大任务数40
控制集群节点间分区迁移力度。
server_data_copy_out_concurrency该OBServer节点分区复制任务流出的最大任务数。10
控制单个节点分区迁移数据读出力度。
server_data_copy_in_concurrency该OBServer节点分区复制任务流入的最大任务数。10
控制单个节点分区迁移数据写入力度。
sys_bkgd_net_percentage

sys后台线程使用网络流量比例上限

60

这个参数比例过高可能导致大部分网卡流量被后台任务(如分区迁移时复制分区数据)占满,可能间接影响业务SQL性能。或者因为分区复制力度太大,间接导致节点磁盘负载过高。
enable_rereplication是否开启副本复制
True
特殊变更期间可以关闭这个。关闭后如果副本数目不足,不会自动补齐副本。

参数修改脚本


注:以上部分参数默认值可能随着版本不同。
手动修改参数一个个改,略麻烦。可以通过下面脚本,批量修改每个节点的参数。脚本里的参数只是内部某个业务场景的配置情况,供参考。
#!/usr/bin/env python
# coding=utf-8

import sys,os,time
import yaml
import MySQLdb
from getopt import getopt, GetoptError


class Option():
OB_CONFIG = """{
ob_cluster_int_params:{
clog_disk_usage_limit_percentage: 90,
data_disk_usage_limit_percentage: 90,
minor_freeze_times: 3,
cpu_reserved: 2,
memory_limit_percentage: 90,
memstore_limit_percentage: 70,
freeze_trigger_percentage: 50,
max_syslog_file_count: 100,
zone_merge_concurrency: 0,
merge_thread_count: 0,
global_write_halt_residual_memory: 30,
global_major_freeze_residual_memory: 40,
minor_merge_concurrency: 0,
large_query_worker_percentage: 30,
sys_bkgd_net_percentage: 60,
user_iort_up_percentage: 100,
sys_bkgd_io_high_percentage: 90,
sys_bkgd_io_low_percentage: 0
},
ob_cluster_str_params:{
autoinc_cache_refresh_interval: 72000s,
syslog_level: INFO,
enable_syslog_recycle: true,
enable_merge_by_turn: false,
major_freeze_duty_time: "02:00",
merger_warm_up_duration_time: 300s,
minor_warm_up_duration_time: 300s,
large_query_threshold: 500ms,
trx_force_kill_threshold: 100ms,
zone_merge_timeout: 3h,
trx_try_wait_lock_timeout: 0ms,
trace_log_slow_query_watermark: 100ms,
syslog_io_bandwidth_limit: 30MB,
default_compress_func: "zstd_1.0"
}
}
"""

hosts = os.getenv('OB_SERVER_IP_LIST', '127.1')
host = hosts.split(',')[0]
port = int(os.getenv('OB_SERVER_SQL_PORT', 2881))
user = 'root@sys'
password = os.getenv('OB_SERVER_PASSWD', '')
database = 'oceanbase'
params = yaml.load(OB_CONFIG)

class ObConn():
def __init__(self):
self.conn = MySQLdb.connect(host=Option.host, port=Option.port, user=Option.user, passwd=Option.password, db=Option.database)

def run_sql(self, sql_str):
try:
cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
rows_count = cursor.execute(sql_str)
except MySQLdb.Error as err:
print(err)
sys.exit(1)
else:
if rows_count > 0:
rows = cursor.fetchall()
cursor.close()
return rows
else:
cursor.close()
return None

def close(self):
self.conn.close()

def parse_arg():
try:
opts, args = getopt(sys.argv[1:], "h:P:u:p:", ["help", "host=", "port=", "password="])
except GetoptError as err:
print str(err)
print('Usage: python obparam.py [-h|--host=HOST] [-P|--port=PORT] [-u|--user=USER] [-p|--password=PASSWORD]')
sys.exit(1)
for o, v in opts:
if o == "--help":
usage()
sys.exit(1)
elif o in ("-h", "--host"):
Option.host = v
elif o in ("-P", "--port"):
Option.port = int(v)
elif o in ("-p", "--password"):
Option.password = v
elif o in ("-u", "--user"):
Option.user = v
else:
assert False, "unhandled option"

def Main():
parse_arg()
db_conn = ObConn()
for k,v in Option.params['ob_cluster_int_params'].iteritems():
db_conn.run_sql("alter system set {0} = {1}".format(k, int(v)))
print(k, v)
for k,v in Option.params['ob_cluster_str_params'].iteritems():
db_conn.run_sql("alter system set {0} = '{1}'".format(k, v))
print(k, v)

if __name__ == "__main__":
Main()

运行脚本前,需要安装相关python模块
sudo yum -y install MySQL-python.x86_64 PyYAML.x86_64

推荐阅读


文章转载自数据库技术闲谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论