[ https://issues.apache.org/jira/browse/PHOENIX-7370?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Viraj Jasani updated PHOENIX-7370: ---------------------------------- Description: HBase uses RPC (Remote Procedure Call) framework for all the wire communication among its components e.g. client to server (client to master daemon or client to regionservers) as well as server to server (master to regionserver, regionserver to regionserver) communication. HBase RPC uses Google's Protocol Buffers (protobuf) for defining the structure of messages sent between clients and servers. Protocol Buffers allow efficient serialization and deserialization of data, which is crucial for performance. HBase defines service interfaces using Protocol Buffers, which outline the operations that clients can request from HBase servers. These interfaces define methods like get, put, scan, etc., that clients use to interact with the database. HBase also provides Coprocessors. HBase Coprocessors are used to extend the regionservers functionalities. They allow custom code to execute within the context of the regionserver during specific phases of the given workflow, such as during data reads (preScan, postScan etc), writes (preBatchMutate, postBatchMutate etc), region splits or even at the start or end of regionserver operations. In addition to being SQL query engine, Phoenix is also a Coprocessor component. RPC framework using Protobuf is used to define how coprocessor endpoints communicate between clients and the coprocessors running on the regionservers. Phoenix client creates CQSI connection ({{{}ConnectionQueryServices{}}}), which maintains long time TCP connection with HBase server, usually knowns as {{HConnection}} or HBase Connection. Once the connection is created, it is cached by the Phoenix client. While PHOENIX-6066 is considered the correct fix to improve the query performance, releasing it has surfaced other issues related to RPC framework. One of the issues surfaced caused deadlock for SYSTEM.CATALOG serving regionserver as it could not make any more progress because all handler threads serving RPC calls for Phoenix system tables (thread pool: {{{}RpcServer.Metadata.Fifo.handler{}}}) got exhausted while creating server side connection from the given regionserver. Several workflows from MetaDataEndpointImpl coproc requires Phoenix connection, which is usually CQSI connection. Phoenix differentiates CQSI connections initiated by clients and servers by using a property: {{{}IS_SERVER_CONNECTION{}}}. For CQSI connections created by servers, IS_SERVER_CONNECTION is kept true. Under heavy load, when several clients execute getTable() calls for the same base table simultaneously, MetaDataEndpointImpl coproc attempts to create server side CQSI connection initially. As CQSI initialization also depends on Phoenix system tables existence check as well as client to server version compatibility checks, it also performs MetaDataEndpointImpl#getVersion() RPC call which is meant to be served by RpcServer.Metadata.Fifo.handler thread-pool. However, under heavy load, the thread-pool can be completely occupied if all getTable() calls tries to initiate CQSI connection, whereas only single thread can take global CQSI lock to initiate HBase Connection before caching CQSI connection for other threads to use. This has potential to create deadlock. h3. Solutions: * Phoenix server to server system table RPC calls are supposed to be using separate handler thread-pools (PHOENIX-6687). However, this is not correctly working because regardless of whether the HBase Connection is initiated by client or server, Phoenix only provides ClientRpcControllerFactory by default. We need to provide separate RpcControllerFactory during HBase Connection initialization done by Coprocessors that operate on regionservers. * For Phoenix server creating CQSI connection, we do not need to check for existence of system tables as well as client-server version compatibility. This redundant RPC call can be avoided. Doc on HBase/Phoenix RPC Scheduler Framework: https://docs.google.com/document/d/12SzcAY3mJVsN0naMnq45qsHcUIk1CzHsAI0EOi6IIgg/edit?usp=sharing was: HBase uses RPC (Remote Procedure Call) framework for all the wire communication among its components e.g. client to server (client to master daemon or client to regionservers) as well as server to server (master to regionserver, regionserver to regionserver) communication. HBase RPC uses Google's Protocol Buffers (protobuf) for defining the structure of messages sent between clients and servers. Protocol Buffers allow efficient serialization and deserialization of data, which is crucial for performance. HBase defines service interfaces using Protocol Buffers, which outline the operations that clients can request from HBase servers. These interfaces define methods like get, put, scan, etc., that clients use to interact with the database. HBase also provides Coprocessors. HBase Coprocessors are used to extend the regionservers functionalities. They allow custom code to execute within the context of the regionserver during specific phases of the given workflow, such as during data reads (preScan, postScan etc), writes (preBatchMutate, postBatchMutate etc), region splits or even at the start or end of regionserver operations. In addition to being SQL query engine, Phoenix is also a Coprocessor component. RPC framework using Protobuf is used to define how coprocessor endpoints communicate between clients and the coprocessors running on the regionservers. Phoenix client creates CQSI connection ({{{}ConnectionQueryServices{}}}), which maintains long time TCP connection with HBase server, usually knowns as {{HConnection}} or HBase Connection. Once the connection is created, it is cached by the Phoenix client. While PHOENIX-6066 is considered the correct fix to improve the query performance, releasing it has surfaced other issues related to RPC framework. One of the issues surfaced caused deadlock for SYSTEM.CATALOG serving regionserver as it could not make any more progress because all handler threads serving RPC calls for Phoenix system tables (thread pool: {{{}RpcServer.Metadata.Fifo.handler{}}}) got exhausted while creating server side connection from the given regionserver. Several workflows from MetaDataEndpointImpl coproc requires Phoenix connection, which is usually CQSI connection. Phoenix differentiates CQSI connections initiated by clients and servers by using a property: {{{}IS_SERVER_CONNECTION{}}}. For CQSI connections created by servers, IS_SERVER_CONNECTION is kept true. Under heavy load, when several clients execute getTable() calls for the same base table simultaneously, MetaDataEndpointImpl coproc attempts to create server side CQSI connection initially. As CQSI initialization also depends on Phoenix system tables existence check as well as client to server version compatibility checks, it also performs MetaDataEndpointImpl#getVersion() RPC call which is meant to be served by RpcServer.Metadata.Fifo.handler thread-pool. However, under heavy load, the thread-pool can be completely occupied if all getTable() calls tries to initiate CQSI connection, whereas only single thread can take global CQSI lock to initiate HBase Connection before caching CQSI connection for other threads to use. This has potential to create deadlock. h3. Solutions: * Phoenix server to server system table RPC calls are supposed to be using separate handler thread-pools (PHOENIX-6687). However, this is not correctly working because regardless of whether the HBase Connection is initiated by client or server, Phoenix only provides ClientRpcControllerFactory by default. We need to provide separate RpcControllerFactory during HBase Connection initialization done by Coprocessors that operate on regionservers. * For Phoenix server creating CQSI connection, we do not need to check for existence of system tables as well as client-server version compatibility. This redundant RPC call can be avoided. > Server to server system table RPC calls should use separate RPC handler pool > ---------------------------------------------------------------------------- > > Key: PHOENIX-7370 > URL: https://issues.apache.org/jira/browse/PHOENIX-7370 > Project: Phoenix > Issue Type: Improvement > Affects Versions: 5.2.0 > Reporter: Viraj Jasani > Assignee: Viraj Jasani > Priority: Major > > HBase uses RPC (Remote Procedure Call) framework for all the wire > communication among its components e.g. client to server (client to master > daemon or client to regionservers) as well as server to server (master to > regionserver, regionserver to regionserver) communication. HBase RPC uses > Google's Protocol Buffers (protobuf) for defining the structure of messages > sent between clients and servers. Protocol Buffers allow efficient > serialization and deserialization of data, which is crucial for performance. > HBase defines service interfaces using Protocol Buffers, which outline the > operations that clients can request from HBase servers. These interfaces > define methods like get, put, scan, etc., that clients use to interact with > the database. > HBase also provides Coprocessors. HBase Coprocessors are used to extend the > regionservers functionalities. They allow custom code to execute within the > context of the regionserver during specific phases of the given workflow, > such as during data reads (preScan, postScan etc), writes (preBatchMutate, > postBatchMutate etc), region splits or even at the start or end of > regionserver operations. In addition to being SQL query engine, Phoenix is > also a Coprocessor component. RPC framework using Protobuf is used to define > how coprocessor endpoints communicate between clients and the coprocessors > running on the regionservers. > Phoenix client creates CQSI connection ({{{}ConnectionQueryServices{}}}), > which maintains long time TCP connection with HBase server, usually knowns as > {{HConnection}} or HBase Connection. Once the connection is created, it is > cached by the Phoenix client. > While PHOENIX-6066 is considered the correct fix to improve the query > performance, releasing it has surfaced other issues related to RPC framework. > One of the issues surfaced caused deadlock for SYSTEM.CATALOG serving > regionserver as it could not make any more progress because all handler > threads serving RPC calls for Phoenix system tables (thread pool: > {{{}RpcServer.Metadata.Fifo.handler{}}}) got exhausted while creating server > side connection from the given regionserver. > Several workflows from MetaDataEndpointImpl coproc requires Phoenix > connection, which is usually CQSI connection. Phoenix differentiates CQSI > connections initiated by clients and servers by using a property: > {{{}IS_SERVER_CONNECTION{}}}. > For CQSI connections created by servers, IS_SERVER_CONNECTION is kept true. > Under heavy load, when several clients execute getTable() calls for the same > base table simultaneously, MetaDataEndpointImpl coproc attempts to create > server side CQSI connection initially. As CQSI initialization also depends on > Phoenix system tables existence check as well as client to server version > compatibility checks, it also performs MetaDataEndpointImpl#getVersion() RPC > call which is meant to be served by RpcServer.Metadata.Fifo.handler > thread-pool. However, under heavy load, the thread-pool can be completely > occupied if all getTable() calls tries to initiate CQSI connection, whereas > only single thread can take global CQSI lock to initiate HBase Connection > before caching CQSI connection for other threads to use. This has potential > to create deadlock. > h3. Solutions: > * Phoenix server to server system table RPC calls are supposed to be using > separate handler thread-pools (PHOENIX-6687). However, this is not correctly > working because regardless of whether the HBase Connection is initiated by > client or server, Phoenix only provides ClientRpcControllerFactory by > default. We need to provide separate RpcControllerFactory during HBase > Connection initialization done by Coprocessors that operate on regionservers. > * For Phoenix server creating CQSI connection, we do not need to check for > existence of system tables as well as client-server version compatibility. > This redundant RPC call can be avoided. > > Doc on HBase/Phoenix RPC Scheduler Framework: > https://docs.google.com/document/d/12SzcAY3mJVsN0naMnq45qsHcUIk1CzHsAI0EOi6IIgg/edit?usp=sharing -- This message was sent by Atlassian Jira (v8.20.10#820010)