Я отправляю запросы клиенту Parity Ethereum параллельно от клиента Python. Узел предоставляет интерфейсы RP C и IP C, транспорт RP C - HTTP, а транспорт IP C - сокет Linux. Теоретически, IP C должен быть намного быстрее, чем RP C. Однако когда я отправляю запросы от многих процессов параллельно, RP C хорошо масштабируется, а IP C - нет. Вот мой код:
prov = None
def test_rpc_perf(ipc_path: str, block_no):
global prov
if prov is None:
if ipc_path.startswith("http"):
print("RPC")
prov = Web3.HTTPProvider("http://localhost:8545")
else:
print("IPC")
prov = Web3.IPCProvider(ipc_path)
block = prov.make_request("eth_getBlockByNumber", [hex(block_no), True])["result"]
for tx in block["transactions"]:
tx2 = prov.make_request("eth_getTransactionReceipt", [tx["hash"]])["result"]
if block_no % 10 == 0:
print(block_no)
if __name__ == "__main__":
import sys, time
tm = time.time()
f = partial(test_rpc_perf, sys.argv[1])
blocks = range(5000000,5000100)
with futures.ProcessPoolExecutor(1) as executor:
executor.map(f, blocks)
print(time.time() - tm)
С 1 работником требуется 60 секунд для RP C и 18 секунд для IP C, чтобы получить квитанцию для всех транзакций в 100 блоках. Это логично - IP C быстрее чем RP C по HTTP. Однако при 10 рабочих и 1000 блоков это занимает 130 секунд для IP C и 60 секунд для RP C. Как мы видим, для RP C он линейный - один рабочий обрабатывает 100 блоков за 60 секунд, 10 рабочих обрабатывают 1000 блоков за 60 секунд (машина довольно мощная, Parity может получить все необходимые ей ресурсы). Однако для IP C один рабочий обрабатывает 100 блоков за 18 секунд, а 10 рабочих обрабатывают 1000 блоков за 130 секунд. При работе с несколькими рабочими практически нет прироста производительности (помните, что 1 рабочий может обработать 100 блоков за 18 секунд). Пробовал 1000 блоков и 1 IP C работник - заняло 164 секунды.
Есть ли принципиальная проблема при использовании IP C параллельно? Для HTTP несколько клиентов просто создают сокет-соединения с сервером, который затем обрабатывает сервер параллельно. Может ли та же парадигма применяться к IP C, только с разными типами сокетов, или она настолько отличается, что будет работать только последовательный доступ?