PostgreSQL中citus节点间的网络需求有哪些
本篇内容介绍了“PostgreSQL中citus节点间的网络需求有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
背景citus 节点间的网络需求:
1、cn节点访问所有worker节点。oltp业务的访问较频繁。
2、重分布数据时,worker节点间相互访问。访问频度不大,OLAP业务常见,一旦有可能数据交换吞吐较大。
citus的cn节点连worker节点为有两种模式,
一种为事务级保持连接模式(每条SQL发起时建立连接,SQL结束后释放连接(除非在事务中,否则SQL结束立即释放连接)。),
另一种为会话级保持连接模式(会话发起时建立连接,会话结束后释放连接。)。
1、跑OLAP类的SQL时,使用的是第一种即时连接模式(OLAP场景并发不高,建立连接带来的额外开销不明显)
可以在worker节点打开参数进行跟踪
postgres=#showlog_connections;log_connections-----------------on(1row)postgres=#showlog_disconnections;log_disconnections--------------------on(1row)
例子,
以下两条SQL均为即时短连接模式(Custom Scan (Citus Task-Tracker) Custom Scan (Citus Real-Time)
)。
postgres=#setcitus.task_executor_type=task;ERROR:invalidvalueforparameter"citus.task_executor_type":"task"HINT:Availablevalues:real-time,task-tracker.postgres=#setcitus.task_executor_type='task-tracker';SETpostgres=#explainselectcount(*)frompgbench_accounts;QUERYPLAN---------------------------------------------------------------------------------------------------------------------Aggregate(cost=0.00..0.00rows=0width=0)->CustomScan(CitusTask-Tracker)(cost=0.00..0.00rows=0width=0)TaskCount:128TasksShown:Oneof128->TaskNode:host=172.24.211.224port=1921dbname=postgres->Aggregate(cost=231.85..231.86rows=1width=8)->SeqScanonpgbench_accounts_106812pgbench_accounts(cost=0.00..212.48rows=7748width=0)(8rows)postgres=#setcitus.task_executor_type='real-time';postgres=#explainselectcount(*)frompgbench_accounts;QUERYPLAN---------------------------------------------------------------------------------------------------------------------Aggregate(cost=0.00..0.00rows=0width=0)->CustomScan(CitusReal-Time)(cost=0.00..0.00rows=0width=0)TaskCount:128TasksShown:Oneof128->TaskNode:host=172.24.211.224port=1921dbname=postgres->Aggregate(cost=231.85..231.86rows=1width=8)->SeqScanonpgbench_accounts_106812pgbench_accounts(cost=0.00..212.48rows=7748width=0)(8rows)
2、跑OLTP查询时(通常并发很高,前端有连接池(保持会话)),为会话级保持连接模式(Custom Scan (Citus Router)
)。
以下SQL为长连接模式(不会立即释放,而是等会再释放,以降低高并发时连接带来的开销)
postgres=#explainselect*frompgbench_accountswhereaid=5;QUERYPLAN------------------------------------------------------------------------------------------------------------------------------------------CustomScan(CitusRouter)(cost=0.00..0.00rows=0width=0)TaskCount:1TasksShown:All->TaskNode:host=172.24.211.224port=1921dbname=postgres->IndexScanusingpgbench_accounts_pkey_106836onpgbench_accounts_106836pgbench_accounts(cost=0.28..2.50rows=1width=97)IndexCond:(aid=5)(7rows)
看以上两种场景,CITUS应该说设计得已经很不错了。既能满足TP也能满足AP。
但是前面也说了,连接保持是在事务或会话层面的,如果查询量大,或者用户使用了短连接,建立连接的开销就会很凸显。
newdb=>\cpostgrespostgresYouarenowconnectedtodatabase"postgres"asuser"postgres".postgres=#select*frompgbench_accountswhereaid=1;aid|bid|abalance|filler-----+-----+----------+--------------------------------------------------------------------------------------1|1|7214|(1row)Time:11.264ms--包括新建连接的开销postgres=#select*frompgbench_accountswhereaid=1;aid|bid|abalance|filler-----+-----+----------+--------------------------------------------------------------------------------------1|1|7214|(1row)Time:0.905ms--已建立连接使用pgbouncer,解决建立连接的开销
在worker节点上,部署pgbouncer,所有与worker节点建立的连接都通过pgbouncer连接池,以此来保持住连接,降低worker节点频繁新建连接的开销。
部署方法
1、所有worker节点pgbouncer
yuminstall-ypgbouncer
配置
vi/etc/pgbouncer/pgb.ini[databases]newdb=host=/tmpdbname=newdbport=1921user=digoalpool_size=128reserve_pool=10[pgbouncer]logfile=/var/log/pgbouncer/pgbouncer.logpidfile=/var/run/pgbouncer/pgbouncer.pidlisten_addr=0.0.0.0listen_port=8001auth_type=anyauth_file=/etc/pgbouncer/userlist.txtpool_mode=sessionserver_reset_query=DISCARDALLmax_client_conn=5000default_pool_size=128;最大不要超过4倍CPU数
启动
pgbouncer-d-upgbouncer/etc/pgbouncer/pgb.ini
在一个citus集群中,可以同时存在直连worker或者通过pgbouncer连接worker。
不同的database可以有不同的配置。
以下例子,新建一个database,使用pgbouncer连接worker.
2、所有节点(包括cn, worker)新建数据库,插件
su-postgrespsql-c"createroledigoallogin;"psql-c"createdatabasenewdb;"psql-c"grantallondatabasenewdbtodigoal;"psql-Upostgresnewdb-c"createextensioncitus;"cn节点
将worker添加到集群配置,使用pgbouncer的连接端口
su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.224',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.230',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.231',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.225',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.227',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.232',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.226',8001);\""su-postgres-c"psql-Upostgresnewdb-c\"SELECT*frommaster_add_node('xxx.xxx.xxx.229',8001);\""
MX配置,同样,将worker节点添加到元数据同步中。
psqlnewdbpostgres
select*frommaster_add_node('xxx.xxx.xxx.224',8001);select*frommaster_add_node('xxx.xxx.xxx.230',8001);
开启同步到元数据。
selectstart_metadata_sync_to_node('xxx.xxx.xxx.224',8001);selectstart_metadata_sync_to_node('xxx.xxx.xxx.230',8001);测试
1、tpc-b 长连接测试
pgbench-i-s-Udigoalnewdb
psql-Udigoalnewdbselectcreate_distributed_table('pgbench_accounts','aid');selectcreate_distributed_table('pgbench_branches','bid');selectcreate_distributed_table('pgbench_tellers','tid');selectcreate_distributed_table('pgbench_history','aid');
pgbench-Mprepared-v-r-P1-c64-j64-T120-Udigoalnewdb-S
性能与不使用pgbouncer差不多,因为使用了长连接测试简单SQL(本身citus就使用了会话级连接保持,没有短连接问题)。
citus第一次QUERY的隐藏耗时在一个新建的会话中,第一次查询总是需要需要耗费更多的时间(如果没有建立连接,那么包括建立连接的时间。即使已建立连接,也需要耗费额外的一些时间)(具体原因可以跟踪分析一下code)。
以下使用的是pgbouncer连接worker,因此第一次QUERY不包含建立连接的时间。
newdb=>\qpostgres@digoal-citus-gpdb-test001->psqlnewdbdigoalpsql(10.5)Type"help"forhelp.\timingnewdb=>select*frompgbench_accountswhereaid=5;aid|bid|abalance|filler-----+-----+----------+--------------------------------------------------------------------------------------5|1|0|(1row)Time:6.016ms--不包括新建连接(已使用pgbouncer建立),但是也多了几毫秒--但是相比未使用pgbouncer,已经降低了5毫秒左右的延迟。newdb=>select*frompgbench_accountswhereaid=5;aid|bid|abalance|filler-----+-----+----------+--------------------------------------------------------------------------------------5|1|0|(1row)Time:0.989ms
多出的几毫秒,我们社区的小伙伴邓彪、王健给出了原因如下,很多地方需要检查安装的citus版本与citus.control控制文件的版本是否兼容(比如加载分布式TABLE的RELCACHE时,第一次访问就是这个问题),不兼容报错:
详见代码
https://github.com/citusdata/citus/blob/3fa04d8f2c8f27b1377fe4c1468ee47358117e3c/src/backend/distributed/utils/metadata_cache.c
/**CheckAvailableVersioncomparesCITUS_EXTENSIONVERSIONandthecurrently*availableversionfromthecitus.controlfile.Iftheyarenotcompatible,*thisfunctionlogsanerrorwiththespecifiedelevelandreturnsfalse,*otherwiseitreturnstrue.*/boolCheckAvailableVersion(intelevel){char*availableVersion=NULL;if(!EnableVersionChecks){returntrue;}availableVersion=AvailableExtensionVersion();if(!MajorVersionsCompatible(availableVersion,CITUS_EXTENSIONVERSION)){ereport(elevel,(errmsg("loadedCituslibraryversiondiffersfromlatest""availableextensionversion"),errdetail("Loadedlibraryrequires%s,butthelatestcontrol""filespecifies%s.",CITUS_MAJORVERSION,availableVersion),errhint("RestartthedatabasetoloadthelatestCitus""library.")));returnfalse;}returntrue;}/**AvailableExtensionVersionreturnstheCitusversionfromcitus.controlfile.Italso*savestheresult,thusconsecutivecallstoCitusExtensionAvailableVersionwill*notreadthecitus.controlfileagain.*/staticchar*AvailableExtensionVersion(void){ReturnSetInfo*extensionsResultSet=NULL;TupleTableSlot*tupleTableSlot=NULL;FunctionCallInfoData*fcinfo=NULL;FmgrInfo*flinfo=NULL;intargumentCount=0;EState*estate=NULL;boolhasTuple=false;boolgoForward=true;booldoCopy=false;char*availableExtensionVersion;InitializeCaches();estate=CreateExecutorState();extensionsResultSet=makeNode(ReturnSetInfo);extensionsResultSet->econtext=GetPerTupleExprContext(estate);extensionsResultSet->allowedModes=SFRM_Materialize;fcinfo=palloc0(sizeof(FunctionCallInfoData));flinfo=palloc0(sizeof(FmgrInfo));fmgr_info(F_PG_AVAILABLE_EXTENSIONS,flinfo);InitFunctionCallInfoData(*fcinfo,flinfo,argumentCount,InvalidOid,NULL,(Node*)extensionsResultSet);/*pg_available_extensionsreturnsresultsetcontainingallavailableextensions*/(*pg_available_extensions)(fcinfo);tupleTableSlot=MakeSingleTupleTableSlot(extensionsResultSet->setDesc);hasTuple=tuplestore_gettupleslot(extensionsResultSet->setResult,goForward,doCopy,tupleTableSlot);while(hasTuple){DatumextensionNameDatum=0;char*extensionName=NULL;boolisNull=false;extensionNameDatum=slot_getattr(tupleTableSlot,1,&isNull);extensionName=NameStr(*DatumGetName(extensionNameDatum));if(strcmp(extensionName,"citus")==0){MemoryContextoldMemoryContext=NULL;DatumavailableVersion=slot_getattr(tupleTableSlot,2,&isNull);/*wewillcachetheresultofcitusversiontopreventcatalogaccess*/oldMemoryContext=MemoryContextSwitchTo(CacheMemoryContext);availableExtensionVersion=text_to_cstring(DatumGetTextPP(availableVersion));MemoryContextSwitchTo(oldMemoryContext);ExecClearTuple(tupleTableSlot);ExecDropSingleTupleTableSlot(tupleTableSlot);returnavailableExtensionVersion;}ExecClearTuple(tupleTableSlot);hasTuple=tuplestore_gettupleslot(extensionsResultSet->setResult,goForward,doCopy,tupleTableSlot);}ExecDropSingleTupleTableSlot(tupleTableSlot);ereport(ERROR,(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),errmsg("citusextensionisnotfound")));returnNULL;}pgbouncer连接池连接worker的好处
1、对于业务层短连接会有比较好的效果。可以降低至少5毫秒左右的延迟。
2、对于大量复杂查询(需要motion的查询),可以减少节点间的连接数。
“PostgreSQL中citus节点间的网络需求有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。