My most recent high performance layout has 36 datanodes, 2 edge nodes, 3 name nodes.
Data Nodes (36x)
Write Path (always port 4243)
PUT commands were executed via the TELNET protocol. TCollector was configured with the native IP address of both Edge nodes, and would self balance, failover across the 10,000 or so clients.
On each machine in the network, there was the tcp_bridge and udp_bridge collectors which listened on port 4243 so all self-instrumented applications would always push their metrics to "localhost:4243"
When the writes would arrive on the Edge Nodes, the HAProxy instance there would balance the writes across the TSD instances (4243) on each Data Node.
Read Path (always 4242 for OpenTSDB and 4245 for Splicer)
For the query path, there is the same pair of edge nodes as the writes. Queries would hit the floating IP on port 4245 for the Splicer query engine.
Splicer takes an incoming query, breaks it up into 1 hour chunks, and spreads the shared queries across the 10 docker containers on the datanode where that region lives. The 1 hour results are cached in Redis so that Grafana dashboards showing weeks and months of data will work quickly.
Queries could be, and sometimes were, executed against OpenTSDB directly, using port 4242 on the Edge nodes. When this would happen, the HAProxy instance would balance the incoming connections, in HTTP mode, across the HAProxy instances (port 4242) on each Data Node.