Mīļākais jautājums par jebkuru izplatītu sistēmu no netehniskā speciālista ir “Cik tps ir jūsu blokķēdē?”. Tomēr, atbildes sniegtais skaitlis parasti ir ļoti maz saistīts ar to, ko jautātājs vēlētos dzirdēt. Patiesībā viņš vēlējās vaicāt “vai jūsu blokķēde atbilst manām biznesa prasībām”, un šīs prasības nav viens skaitlis, bet gan daudzi nosacījumi — šeit ir gan tīkla nepārtrauktība, gan galīguma prasības, izmēri, darījumu raksturi un daudzi citi parametri. Tāpēc atbilde uz jautājumu “cik tps” visticamāk nebūs vienkārša, un gandrīz nekad nebūs pilnīga. Izplatīta sistēma ar desmitiem un simtiem mezglu, kas veic diezgan sarežģītas aprēķinus, var atrasties milzīgā skaitā dažādu stāvokļu, kas saistīti ar tīkla stāvokli, blokķēdes saturu, tehniskajiem bojājumiem, ekonomiskām problēmām, uzbrukumiem tīklam un daudzām citām problēmām. Fāzes, kurās var rasties veiktspējas problēmas atšķiras no tradicionālajiem pakalpojumiem, un blokķēdes tīkla serveris ir tīkla pakalpojums, kas apvieno datu bāzes, tīmekļa servera un torrent klienta funkcionalitāti, kas padara to ārkārtīgi sarežģītu slodzes profila ziņā visām apakšsistēmām: procesoram, atmiņai, tīklam, glabāšanai.
Sanācis tā, ka decentralizētās tīklus un blokķēdes ir diezgan specifiska un neparasta programmatūra centralizētu programmatūras izstrādātājiem. Tāpēc es vēlētos izcelt svarīgas aspektus par veiktspēju un noturību decentralizētās tīklos, pieejas to mērīšanai un pudeļu kaklu atklāšanai. Mēs apskatīsim dažādas veiktspējas problēmas, kas ierobežo pakalpojumu sniegšanas ātrumu blokķēdēs un atzīmēsim īpašības, kas raksturīgas šāda veida programmatūrai.
Klienta pieprasījuma posmi blokķēdes pakalpojumiem
Lai godīgi runātu par jebkura salīdzinoši sarežģīta pakalpojuma kvalitāti, ir jāņem vērā ne tikai vidējie rādītāji, bet arī maksimālie/minimālie, mediānas, percentīļi. Teorētiski var runāt par 1000 tps kādā blokķēdē, taču, ja 900 darījumu tika veikti ārkārtīgi ātri, bet 100 – „iestrēga” uz dažām sekundēm, tad vidējais laiks, kas aprēķināts visiem darījumiem, nav gluži godīga metrika klientam, kurš dažās sekundēs nevarēja pabeigt darījumu. Laika „bedres”, ko izraisa nokavēti konsensa apļi vai tīkla sadalīšana, var ievērojami sabojāt pakalpojumu, kas testēšanas vidē demonstrēja lielisku veiktspēju.
Lai identificētu šādus bottleneckus, ir nepieciešams labi izprast posmus, kuros reālā blokķēde var saskarties ar grūtībām klientu apkalpošanā. Apskatīsim darījumu piegādes un apstrādes ciklu, kā arī jauna blokķēdes stāvokļa iegūšanu, no kura klients var pārliecināties, ka viņa darījums ir apstrādāts un ņemts vērā.
- darījums tiek veidots klientā
- darījums tiek parakstīts klientā
- klients izvēlas vienu no mezgliem un nosūta tajā savu darījumu
- klients parakstās uz mezgla state database atjauninājumiem, gaidot, kad parādīsies viņa darījuma izpildes rezultāti
- mezgls izplata darījumu pa p2p tīklu
- daži vai viens BP (block producer) apstrādā uzkrātos darījumus, atjauninot state database
- BP izveido jaunu bloku, apstrādājot nepieciešamo darījumu skaitu
- BP izplata jauno bloku pa p2p tīklu
- jaunais bloks tiek piegādāts mezglam, uz kuru vēršas klients
- mezgls atjaunina state database
- mezgls redz atjauninājumu, kas attiecas uz klientu, un nosūta viņam paziņojumu par darījumu
Tagad detalizēti aplūkosim šos posmus un aprakstīsim iespējamās veiktspējas problēmas katrā posmā. Atšķirībā no centralizētām sistēmām, mēs aplūkosim arī koda izpildi tīkla klientu pusē. Ļoti bieži, mērot tps, darījumu apstrādes laiku vāc no mezgliem, nevis no klienta — tas nav pavisam godīgi. Klientam nav svarīgi, cik ātri mezgls apstrādāja viņa darījumu, vissvarīgākais ir tas brīdis, kad ticama informācija par šo darījumu, kas iekļauta blokķēdē, viņam kļūst pieejama. Tieši šī metrikā būtībā ir darījuma izpildes laiks. Tas nozīmē, ka dažādi klienti, pat nosūtot vienu un to pašu darījumu, var iegūt pilnīgi atšķirīgus laikus, kas atkarīgi no kanāla, noslodzes un mezgla tuvuma utt. Tāpēc ir absolūti nepieciešams izmērīt šo laiku klientu pusē, jo tieši šo parametru ir nepieciešams optimizēt.
Darījuma sagatavošana klienta pusē
Sāksim ar pirmajiem diviem punktiem: darījums tiek veidots un parakstīts klienta pusē. Neparasti, bet tieši šī fāze var būt blokķēdes veiktspējas šaurs posms no klienta perspektīvas. Tas ir netipiski centralizētām pakalpojumu sistēmām, kurās visas aprēķināšanas un datu operācijas tiek apstrādātas centrāli, bet klients vienkārši sagatavo īsu pieprasījumu, kas spēj pieprasīt lielu datu vai aprēķinu apjomu, saņemot gatavu rezultātu. Blokķēdēs klienta kods kļūst arvien jaudīgāks, bet blokķēdes kodols — arvien viegls, un masveida aprēķinu uzdevumi tiek nodoti klienta programmatūrai. Blokķēdēs ir klienti, kas var diezgan ilgi sagatavot vienu darījumu (es runāju par dažādiem merkle pierādījumiem, succinct pierādījumiem, threshold parakstiem un citām sarežģītām operācijām klienta pusē). Labs piemērs vieglai on-chain verifikācijai un smagai darījumu sagatavošanai klientā ir piederības pierādīšana sarakstam, balstoties uz Merkle-koku, šeit .
Arī nevajadzētu aizmirst, ka klientu kods ne tikai sūta darījumus blokķēdē, bet vispirms pieprasa blokķēdes stāvokli — un šī darbība var ietekmēt tīkla noslodzi un blokķēdes mezglus. Tāpēc, veicot mērījumus, saprātīgi būtu pēc iespējas pilnīgāk emulēt klientu koda uzvedību. Pat ja jūsu blokķēdē ir parasti viegli klienti, kas veic parakstīšanu uz vienkāršiem darījumiem, lai pārsūtītu kādu aktīvu, ar katru gadu klientu puses aprēķinu apjoms tomēr pieaug, kriptovalūtu algoritmi kļūst spēcīgāki, un šī daļa no apstrādes var kļūt par nozīmīgu pudeļu kaklu nākotnē. Tādēļ esiet uzmanīgi un nepalaidiet garām situāciju, kad darījumā, kas ilgst 3.5s, 2.5s iet uz sagatavošanu un parakstīšanu, un 1.0s — uz nosūtīšanu tīklā un atbildes gaidīšanu. Lai novērtētu riskus, kas saistīti ar šī pudeļu kakla rašanos, jāapkopo metriskās vērtības no klientu mašīnām, ne tikai no blokķēdes mezgliem.
Darījuma nosūtīšana un tā statusa uzraudzība
Nākamais solis ir nosūtīt darījumu izvēlētajam blokķēdes mezglam un saņemt tā statusu par pievienošanu darījumu pūlī. Šis solis ir līdzīgs parastai piekļuvei datu bāzei, mezglam jāieraksta darījums pülā un jāsāk izplatīt informāciju par to caur p2p tīklu. Pieejas novērtēšanai šeit ir līdzīga pieeja kā tradicionālo mikroservisu Web API darbības novērtēšanai, un paši darījumi blokķēdēs var tikt atjaunināti, aktīvi mainot statusu. Kopumā informācijas atjaunināšana par darījumu dažās blokķēdēs var notikt vairākas reizes, piemēram, pārslēdzoties starp ķēdes hard fork'iem vai kad BP ziņo par nodomu iekļaut darījumu blokā. Ierobežojumi uz pūļa apjomu un darījumu skaitu tajā var ietekmēt blokķēdes veiktspēju. Ja darījumu pūlis ir piepildīts līdz maksimāli pieejamajam izmēram vai nav iekļaujams operatīvajā atmiņā — tīkla veiktspēja var strauji samazināties. Blokķēdes nav centralizētu aizsardzības līdzekļu pret nevēlamu ziņojumu plūsmu, un, ja blokķēde atbalsta lielus darījumus un zemas maksas, tas var novest pie darījumu pūļa pārpildīšanas — tas ir vēl viens potenciālais veiktspējas pudeļu kakls.
Blokķēdēs klients nosūta darījumu uz jebkuru viņam tīkamu blokķēdes mezglu, darījuma hashes parasti ir zināms klientam jau pirms nosūtīšanas, tādēļ viss, kas viņam nepieciešams, ir nodrošināt savienojumu un, pēc nodošanas, gaidīt, kad blokķēde izmainīs savu stāvokli, iekļaujot viņa darījumu. Jāpiezīmē, ka, mērot „tps”, var iegūt pilnīgi atšķirīgus rezultātus dažādiem savienojumu veidiem ar blokķēdes mezglu. Tas var būt parasts HTTP RPC vai WebSocket, kas ļauj īstenot „subscribe” paraugu. Otrajā gadījumā klients saņems paziņojumu ātrāk, un mezgls iztērēs mazāk resursu (galvenokārt atmiņas un datu plūsmas) atbildēm par darījuma stāvokli. Tādēļ, mērot „tps”, ir jāņem vērā veids, kā klienti savienojas ar mezgliem. Tāpēc, lai novērtētu šī uzņēmuma riska rašanās iespējamību, blokķēdes benchmarkam jāspēj emulēt klientus gan ar WebSocket, gan ar HTTP RPC pieprasījumiem, proporcijās, kas atbilst reālām tīkla situācijām, kā arī mainīt darījumu raksturu un to lielumu.
Lai novērtētu riskus saistībā ar šo kļūmes punktu, ir arī jāapkopo metriķi no klientu mašīnām, ne tikai no blokķēdes mezgliem.
Darījumu un bloku pārsūtīšana pa p2p tīklu
Blokķēdēs darījumu un bloku pārsūtīšanai starp dalībniekiem tiek izmantota peer-to-peer (p2p) tīklošana. Darījumi tiek izplatīti pa tīklu, sākot no viena no mezgliem, līdz tie sasniedz peer-blokproducentus, kuri iepako darījumus blokos un ar to pašu p2p izplata jaunus blokuss visiem tīkla mezgliem. Lielākās daļas mūsdienu p2p tīklu pamats ir dažādas Kademlia protokola modifikācijas. laba īsa pārskats par šo protokolu, un — raksts ar dažādiem mērījumiem BitTorrent tīklā, no kura var saprast, ka šāda veida tīkli ir sarežģītāki un mazāk prognozējami, nekā stingri konfigurēts centralizēta pakalpojuma tīkls. Tāpat, raksts par dažādu interesantu metriķu mērīšanu Ethereum mezglos.
Ja īsi sakot, katrs peer šādās tīklās uztur savu dinamisko citu peer sarakstu, no kuriem pieprasa informācijas blokus, kas adresēti saturam. Saņemot pieprasījumu, peer vai nu nodod vajadzīgo informāciju, vai arī nodod pieprasījumu nākamajam pseidojaundzimušajam peer no saraksta, un, kad saņem atbildi, to nosūta pieprasītājam un uz kādu laiku kešē, nododot šo informācijas bloku ātrāk nākamreiz. Tādējādi populāra informācija nonāk daudzos kešos pie daudziem peer, bet nepopulārā pakāpeniski tiek izslēgta. Peer uzskaita, cik daudz informācijas katrs ir nodojis, un tīkls cenšas stimulēt aktīvās dalīšanās, paaugstinot viņu vērtējumu un nodrošinot viņiem augstāku pakalpojumu līmeni, automātiski izslēdzot neaktīvus dalībniekus no peer sarakstiem.
Tātad tagad darījumu ir jāizplata tīklā, lai to redzētu bloku ražotāji un iekļautu blokā. Dators aktīvi „izplata” jauno darījumu visiem gribētājiem un klausās tīklā, gaidot blokā, kurā parādīsies nepieciešamā darījuma, lai brīdinātu gaidošo klientu. Laiks, kamēr tīkls apmainās ar informāciju par jauniem darījumiem un blokiem p2p tīklos, ir atkarīgs no ļoti daudziem faktoriem: godīgu, blakus esošu (tīkla skatījumā) datorsistēmu skaita, šo datorsistēmu kešu „uzsildīšanas” pakāpes, blokiem, darījumu lieluma, izmaiņu rakstura, tīkla ģeogrāfijas, datorsistēmu skaita un vēl daudziem citiem faktoriem. Komplicēta veiktspējas metrikas mērīšana šādos tīklos ir sarežģīts uzdevums, jo nepieciešams vienlaikus novērtēt pieprasījumu apstrādes laiku gan klientos, gan peer'os (blokķēdes datorsistēmās). Problēmas kādā no p2p mehānismiem, nepareiza datu pārcelšana un kešatmiņas pārvaldība, neefektīva aktīvo peer'u saraksta pārvaldība un daudzi citi faktori var radīt aizkavēšanos, ietekmējot visas tīkla efektivitāti kopumā, un šis pudeles kakls ir visgrūtāk analizējams, testējams un interpretējams.
Bloku ķēdes apstrāde un state datu bāzes atjaunināšana
Visnozīmīgākā blokķēdes darba daļa ir konsensa algoritms, tā pielietojums jaunajiem, no tīkla saņemtajiem blokiem un darījumu apstrāde ar rezultātu ierakstīšanu state database. Jauna bloka pievienošana ķēdei un tam sekojošā galvenās ķēdes izvēle ir jārealizē pēc iespējas ātrāk. Tomēr reālajā dzīvē „jā” nenozīmē „darbojas”, un var, piemēram, iedomāties situāciju, kad divas garas konkurējošas ķēdes pastāvīgi pārslēdzas starp sev, mainot metadatus tūkstošiem darījumu baseinā katrā pārslēgumā un veicot pastāvīgas stāvokļa atgriešana state database. Šis posms ir vienkāršāks attiecībā uz bottleneck noteikšanu nekā tīkla p2p slānis, jo darījumu izpilde un konsensa algoritms ir stingri determinēti, un šeit ir vieglāk ko mērīt.
Galvenais ir nesajaukt šī posma nejaušo veiktspējas samazināšanos ar tīkla problēmām — mezgli lēnāk sniedz blokāt un informāciju par galveno ķēdi, un ārējam klientam tas var šķist kā lēns tīkls, lai gan problēma slēpjas pavisam citā vietā.
Lai optimizētu veiktspēju šajā posmā, ir noderīgi vākt un uzraudzīt metrikas no pašiem mezgliem, un iekļaut tajās tās, kas attiecas uz state-database atjauninājumiem: apstrādāto bloku skaitu mezglā, to izmēru, transakciju skaitu, pārslogojumu skaitu starp ķēdes forkām, nederīgu bloku skaitu, virtuālās mašīnas darbības laiku, datu fiksēšanas laiku utt. Tas palīdzēs nesajaukt tīkla problēmas ar kļūdām ķēdes apstrādes algoritmos.
Transakciju apstrādājošā virtuālā mašīna var būt noderīgs informācijas avots, kas spēj optimizēt blokķēdes darbību. Atmiņas alokāciju skaits, lasīšanas/rakstīšanas instrukciju skaits un citas metrikas, kas attiecas uz līgumu koda izpildes efektivitāti, var sniegt daudz noderīgas informācijas izstrādātājiem. Tajā pašā laikā viedlīgumi ir programmas, tādējādi teorētiski tās var patērēt jebkādus resursus: cpu/memory/network/storage, tāpēc transakciju apstrāde ir diezgan nenoteikts posms, kas papildus ļoti mainās pārejot no versijas uz versiju un mainot līgumu kodu. Tādēļ metriskas, kas attiecas uz transakciju apstrādi, arī ir nepieciešamas, lai efektīvi optimizētu blokķēdes veiktspēju.
Klients saņem paziņojumu par transakcijas iekļaušanu blokķēdē
Šis ir pēdējais posms, kad klients saņem blokķēdes pakalpojumu. Salīdzinājumā ar citiem posmiem te nav lielu administratīvo izdevumu, bet tomēr ir jāņem vērā iespēja, ka klients saņems apjomīgu atbildi no mezgla (piemēram, viedais līgums, kas dod datu masīvu). Katrā ziņā šis brīdis ir pats svarīgākais tam, kas uzdeva jautājumu "cik tps ir jūsu blokķēdē?", jo tieši šajā brīdī tiek fiksēts pakalpojuma saņemšanas laiks.
Šajā vietā obligāti jābūt norādei uz kopējo laiku, kas klientam bija jāsagaida atbilde no blokķēdes, tieši šo laiku lietotājs gaidīs apstiprinājumu savā lietotnē, un tieši tā optimizācija ir galvenais izstrādātāju uzdevums.
Secinājums
Rezultātā var aprakstīt operāciju veidus, kas tiek veikti blokķēdēs, un sadalīt tos vairākās kategorijās:
- kriptogrāfiskās pārvērtības, pierādījumu veidošana
- peer-to-peer tīklošana, transakciju un bloku replikācija
- transakciju apstrāde, viedlīgumu izpilde
- izmaiņu piemērošana blokķēdē stāvokļa datu bāzei, datu par transakcijām un blokiem atjaunināšana
- lasīšanas pieprasījumi uz stāvokļa datu bāzi, blokķēdes mezgla API, abonēšanas pakalpojumi
Mūsdienu blokķēžu mezglu tehniskajām prasībām ir ļoti augstas — tas ir ātrs CPU šifrēšanai, liels operatīvās atmiņas apjoms, lai uzglabātu un ātri piekļūtu stāvokļa datu bāzei, tīkla mijiedarbība, kas izmanto lielu skaitu vienlaicīgi atvērtu savienojumu, plašs uzglabāšanas apjoms. Šīs augstās prasības un dažādu operāciju pārmērība neizbēgami noved pie tā, ka mezglam var trūkt resursu, un tad jebkura no iepriekš minētajām darbībām var kļūt par nākamo šaurāko vietu (bottleneck) vispārējā tīkla veiktspējā.
Izstrādājot un novērtējot blokķēdes veiktspēju, jums būs jāņem vērā visi šie aspekti. Tam nepieciešams vākt un analizēt metriku vienlaikus no klientiem un tīkla mezgliem, meklēt korelācijas starp tām, novērtēt pakalpojuma sniegšanas laiku klientiem, ņemot vērā visus galvenos resursus: CPU/memory/network/storage, izprast, kā tie tiek izmantoti un ietekmē viens otru. Visi šie aspekti padara dažādu blokķēžu ātruma salīdzināšanu ar jautājumu "cik TPS" par ārkārtīgi pateicīgu uzdevumu, jo pastāv milzīgs dažādu konfigurāciju un stāvokļu kopums. Lielās centralizētās sistēmās, kas sastāv no simtiem serveru, arī ir sarežģītas problēmas, un tās prasa vākšanu lielam skaitam dažādu metriku, bet blokķēdēs, pateicoties P2P tīklam, virtuālajām mašīnām un viedajiem līgumiem, iekšējai ekonomikai, brīvības pakāpe ir daudz lielāka, kas padara testus pat uz vairākiem serveriem par nepietiekamiem un sniedz tikai ļoti aptuvenu vērtību, kam ir maz saistības ar realitāti.
Tāpēc, izstrādājot blokķēdes kodu, veiktspējas novērtējuma un jautājuma "vai tas uzlabojies salīdzinājumā ar iepriekšējo reizi" atbildē mēs izmantojam diezgan sarežģītu programmatūru, kas orchestrē blokķēdes palaišanu ar desmitiem mezglu un automātisku benchmark un metriku vākšanu. Bez šīs informācijas ir ārkārtīgi grūti pārbaudīt protokolus, kas darbojas ar daudzām dalībnieku personām.
Tātad, saņemot jautājumu "cik TPS ir jūsu blokķēdē?", piedāvājiet sarunbiedram tēju un noskaidrojiet, vai viņš ir gatavs iepazīties ar desmit grafikiem, kā arī uzklausīt visas trīs lielās blokķēdes veiktspējas problēmas un jūsu ieteikumus to risināšanai...
Avots: habr.com
