Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke

Ovo nije ni šala, čini se da upravo ova slika najpreciznije odražava suštinu ovih baza podataka, a na kraju će biti jasno zašto:

Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke

Prema rangiranju DB-Engines, dvije najpopularnije NoSQL kolonske baze podataka su Cassandra (u daljem tekstu CS) i HBase (HB).

Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke

Voljom sudbine, naš tim za upravljanje učitavanjem podataka u Sberbanci već jeste davno i blisko sarađuje sa HB. Za to vrijeme smo prilično dobro proučili njegove vrline i mane i naučili kako ga kuhati. Međutim, prisustvo alternative u obliku CS-a uvijek nas je tjeralo da se malo mučimo sumnjama: jesmo li napravili pravi izbor? Štaviše, rezultati poređenja, u izvedbi DataStaxa, rekli su da CS lako pobjeđuje HB sa skoro poraznim rezultatom. S druge strane, DataStax je zainteresovana strana i ne treba im vjerovati na riječ. Zbunila nas je i prilično mala količina informacija o uslovima testiranja, pa smo odlučili da sami saznamo ko je kralj BigData NoSql-a, a dobijeni rezultati su se pokazali veoma zanimljivim.

Međutim, prije nego što pređemo na rezultate provedenih testova, potrebno je opisati značajne aspekte konfiguracije okruženja. Činjenica je da se CS može koristiti u načinu koji omogućava gubitak podataka. One. to je kada je samo jedan server (čvor) odgovoran za podatke određenog ključa, a ako iz nekog razloga ne uspije, vrijednost ovog ključa će biti izgubljena. Za mnoge poslove to nije kritično, ali za bankarski sektor to je prije izuzetak nego pravilo. U našem slučaju, važno je imati nekoliko kopija podataka za pouzdano skladištenje.

Stoga je uzet u obzir samo režim rada CS u režimu trostruke replikacije, tj. Kreiranje prostora slučaja je izvršeno sa sljedećim parametrima:

CREATE KEYSPACE ks WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'datacenter1' : 3};

Zatim, postoje dva načina da se osigura potreban nivo konzistentnosti. Opšte pravilo:
NW + NR > RF

Što znači da broj potvrda iz čvorova prilikom pisanja (NW) plus broj potvrda iz čvorova prilikom čitanja (NR) mora biti veći od faktora replikacije. U našem slučaju, RF = 3, što znači da su prikladne sljedeće opcije:
2 + 2 > 3
3 + 1 > 3

Budući da nam je od suštinske važnosti da podatke pohranimo što je moguće pouzdanije, odabrana je šema 3+1. Osim toga, HB radi na sličnom principu, tj. takvo poređenje će biti pravednije.

Treba napomenuti da je DataStax u svojoj studiji učinio suprotno, postavili su RF = 1 i za CS i za HB (za ovo drugo promjenom HDFS postavki). Ovo je zaista važan aspekt jer je uticaj na performanse CS-a u ovom slučaju ogroman. Na primjer, slika ispod prikazuje povećanje vremena potrebnog za učitavanje podataka u CS:

Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke

Ovdje vidimo sljedeće: što više konkurentskih niti pišu podatke, to je duže potrebno. Ovo je prirodno, ali je važno da je degradacija performansi za RF=3 znatno veća. Drugim riječima, ako upišemo 4 niti u 5 tabele (ukupno 20), onda RF=3 gubi oko 2 puta (150 sekundi za RF=3 naspram 75 za RF=1). Ali ako povećamo opterećenje učitavanjem podataka u 8 tabela sa po 5 niti (ukupno 40), onda je gubitak RF=3 već 2,7 puta (375 sekundi naspram 138).

Možda je to dijelom tajna uspješnog testiranja opterećenja koje je izvršio DataStax za CS, jer za HB na našem štandu promjena faktora replikacije sa 2 na 3 nije imala nikakvog efekta. One. diskovi nisu HB usko grlo za našu konfiguraciju. Međutim, tu ima mnogo drugih zamki, jer treba napomenuti da je naša verzija HB-a malo zakrpljena i dotjerana, okruženja su potpuno drugačija itd. Također je vrijedno napomenuti da možda jednostavno ne znam kako pravilno pripremiti CS i da postoje neki efikasniji načini za rad s njim, a nadam se da ćemo to saznati u komentarima. Ali prvo stvari.

Svi testovi su obavljeni na hardverskom klasteru koji se sastoji od 4 servera, svaki sa sljedećom konfiguracijom:

CPU: Xeon E5-2680 v4 @ 2.40GHz 64 niti.
Diskovi: 12 komada SATA HDD
java verzija: 1.8.0_111

CS verzija: 3.11.5

cassandra.yml parametribroj_žetona: 256
hinted_handoff_enabled: istina
hinted_handoff_throttle_in_kb: 1024
max_hints_delivery_threads: 2
hints_directory: /data10/cassandra/hints
hints_flush_period_in_ms: 10000
max_hints_file_size_in_mb: 128
batchlog_replay_throttle_in_kb: 1024
autentifikator: AllowAllAuthenticator
autorizator: AllowAllAuthorizer
role_manager: CassandraRoleManager
roles_validity_in_ms: 2000
permissions_validity_in_ms: 2000
vjerodostojnost_vrijednosti_u_ms: 2000
particioner: org.apache.cassandra.dht.Murmur3Partitioner
data_file_directories:
- /data1/cassandra/data # svaki dataN direktorij je zaseban disk
- /data2/cassandra/data
- /data3/cassandra/data
- /data4/cassandra/data
- /data5/cassandra/data
- /data6/cassandra/data
- /data7/cassandra/data
- /data8/cassandra/data
commitlog_directory: /data9/cassandra/commitlog
cdc_enabled: lažno
disk_failure_policy: stop
commit_failure_policy: stop
ready_statements_cache_size_mb:
thrift_prepared_statements_cache_size_mb:
key_cache_size_in_mb:
key_cache_save_period: 14400
row_cache_size_in_mb: 0
row_cache_save_period: 0
counter_cache_size_in_mb:
counter_cache_save_period: 7200
saved_caches_directory: /data10/cassandra/saved_caches
commitlog_sync: periodično
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32
seed_provider:
- naziv_ klase: org.apache.cassandra.locator.SimpleSeedProvider
parametri:
— sjemenke: "*,*"
concurrent_reads: 256 # pokušao 64 - nije primjećena razlika
concurrent_writes: 256 # pokušao 64 - nije primjećena razlika
concurrent_counter_writes: 256 # pokušao 64 - nije primjećena razlika
istovremeni_materijalizovani_pregled_piše: 32
memtable_heap_space_in_mb: 2048 # pokušao 16 GB - bilo je sporije
memtable_allocation_type: heap_buffers
index_summary_capacity_in_mb:
index_summary_resize_interval_in_minutes: 60
trickle_fsync: lažno
trickle_fsync_interval_in_kb: 10240
storage_port: 7000
ssl_storage_port: 7001
Adresa_slušanja: *
adresa_emisije: *
listen_on_broadcast_address: istina
internode_authenticator: org.apache.cassandra.auth.AllowAllInternodeAuthenticator
start_native_transport: istina
native_transport_port: 9042
start_rpc: istina
rpc_address: *
rpc_port: 9160
rpc_keepalive: istina
rpc_server_type: sinhronizacija
thrift_framed_transport_size_in_mb: 15
incremental_backups: false
snapshot_before_compaction: lažno
auto_snapshot: istina
veličina_indeksa_kolone_u_kb: 64
column_index_cache_size_in_kb: 2
istovremeni_kompaktori: 4
compaction_throughput_mb_per_sec: 1600
sstable_preemptive_open_interval_in_mb: 50
read_request_timeout_in_ms: 100000
raspon_request_timeout_in_ms: 200000
write_request_timeout_in_ms: 40000
counter_write_request_timeout_in_ms: 100000
cas_contention_timeout_in_ms: 20000
truncate_request_timeout_in_ms: 60000
request_timeout_in_ms: 200000
slow_query_log_timeout_in_ms: 500
cross_node_timeout: lažno
endpoint_snitch: GossipingPropertyFileSnitch
dynamic_snitch_update_interval_in_ms: 100
dynamic_snitch_reset_interval_in_ms: 600000
dynamic_snitch_badness_threshold: 0.1
request_scheduler: org.apache.cassandra.scheduler.NoScheduler
server_encryption_options:
internode_encryption: nema
client_encryption_options:
omogućeno: lažno
internode_compression: dc
inter_dc_tcp_nodelay: lažno
tracetype_query_ttl: 86400
tracetype_repair_ttl: 604800
enable_user_defined_functions: netačno
enable_scripted_user_defined_functions: netačno
windows_timer_interval: 1
transparent_data_encryption_options:
omogućeno: lažno
tombstone_warn_threshold: 1000
tombstone_failure_threshold: 100000
batch_size_warn_threshold_in_kb: 200
batch_size_fail_threshold_in_kb: 250
unlogged_batch_across_partitions_warn_threshold: 10
compaction_large_partition_warning_threshold_mb: 100
gc_warn_threshold_in_ms: 1000
back_pressure_enabled: netačno
enable_materialized_views: istina
enable_sasi_indexes: istina

GC postavke:

### CMS postavke-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:Omjer preživljavanja=8
-XX:MaxTenuringThreshold=1
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSWaitDuration=10000
-XX:+CMSParallelInitialMarkEnabled
-XX:+CMSEdenChunksRecordAlways
-XX:+CMSClassUnloadingEnabled

Memoriji jvm.options je dodeljeno 16Gb (probali smo i 32Gb, razlika nije primećena).

Tabele su kreirane naredbom:

CREATE TABLE ks.t1 (id bigint PRIMARY KEY, title text) WITH compression = {'sstable_compression': 'LZ4Compressor', 'chunk_length_kb': 64};

HB verzija: 1.2.0-cdh5.14.2 (u klasi org.apache.hadoop.hbase.regionserver.HRegion isključili smo MetricsRegion što je dovelo do GC-a kada je broj regija bio veći od 1000 na RegionServeru)

Nepodrazumevani parametri HBasezookeeper.session.timeout: 120000
hbase.rpc.timeout: 2 minuta
hbase.client.scanner.timeout.period: 2 minute
hbase.master.handler.count: 10
hbase.regionserver.lease.period, hbase.client.scanner.timeout.period: 2 minute
hbase.regionserver.handler.count: 160
hbase.regionserver.metahandler.count: 30
hbase.regionserver.logroll.period: 4 sat(a)
hbase.regionserver.maxlogs: 200
hbase.hregion.memstore.flush.size: 1 GiB
hbase.hregion.memstore.block.multiplier: 6
hbase.hstore.compactionThreshold: 5
hbase.hstore.blockingStoreFiles: 200
hbase.hregion.majorcompaction: 1 dan(a)
Isječak napredne konfiguracije usluge HBase (sigurnosni ventil) za hbase-site.xml:
hbase.regionserver.wal.codecorg.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec
hbase.master.namespace.init.timeout3600000
hbase.regionserver.optionalcacheflushinterval18000000
hbase.regionserver.thread.compaction.large12
hbase.regionserver.wal.enablecompressiontrue
hbase.hstore.compaction.max.size1073741824
hbase.server.compactchecker.interval.multiplier200
Java konfiguracijske opcije za HBase RegionServer:
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=256m
hbase.snapshot.master.timeoutMillis: 2 minuta
hbase.snapshot.region.timeout: 2 minuta
hbase.snapshot.master.timeout.millis: 2 minute
Maksimalna veličina dnevnika HBase REST servera: 100 MiB
Maksimalan broj rezervnih kopija datoteka dnevnika HBase REST servera: 5
HBase Thrift Server Maksimalna veličina dnevnika: 100 MiB
Maksimalan broj rezervnih kopija datoteka dnevnika HBase Thrift Server: 5
Master maksimalna veličina dnevnika: 100 MiB
Maksimalna rezervna kopija datoteke dnevnika: 5
RegionServer maksimalna veličina dnevnika: 100 MiB
Maksimalni broj rezervnih kopija datoteke dnevnika RegionServer: 5
HBase Active Master Detection Window: 4 minute (s)
dfs.client.hedged.read.threadpool.size: 40
dfs.client.hedged.read.threshold.millis: 10 milisekundi
hbase.rest.threads.min: 8
hbase.rest.threads.max: 150
Maksimalni deskriptori datoteke procesa: 180000
hbase.thrift.minWorkerThreads: 200
hbase.master.executor.openregion.threads: 30
hbase.master.executor.closeregion.threads: 30
hbase.master.executor.serverops.threads: 60
hbase.regionserver.thread.compaction.small: 6
hbase.ipc.server.read.threadpool.size: 20
Teme pokretača regiona: 6
Veličina klijentske Java hrpe u bajtovima: 1 GiB
HBase REST server Podrazumevana grupa: 3 GiB
HBase Thrift Server Zadana grupa: 3 GiB
Java Heap Veličina HBase Master u bajtovima: 16 GiB
Java Heap Veličina HBase RegionServera u bajtovima: 32 GiB

+ZooKeeper
maxClientCnxns: 601
maxSessionTimeout: 120000
Kreiranje tabela:
hbase org.apache.hadoop.hbase.util.RegionSplitter ns:t1 UniformSplit -c 64 -f cf
alter 'ns:t1', {NAME => 'cf', DATA_BLOCK_ENCODING => 'FAST_DIFF', COMPRESSION => 'GZ'}

Ovdje postoji jedna važna stvar - opis DataStax-a ne kaže koliko je regija korišteno za kreiranje HB tabela, iako je to kritično za velike količine. Stoga je za testove odabrana količina = 64, što omogućava pohranjivanje do 640 GB, tj. stol srednje veličine.

U vreme testiranja, HBase je imao 22 hiljade tabela i 67 hiljada regiona (ovo bi bilo smrtonosno za verziju 1.2.0 da nije gore pomenuta zakrpa).

Sada za kod. Budući da nije bilo jasno koje su konfiguracije povoljnije za određenu bazu podataka, testovi su provedeni u različitim kombinacijama. One. u nekim testovima 4 tabele su učitane istovremeno (sva 4 čvora su korišćena za povezivanje). U ostalim testovima radili smo sa 8 različitih tablica. U nekim slučajevima, veličina serije je bila 100, u drugim 200 (parametar serije - pogledajte kod ispod). Veličina podataka za vrijednost je 10 bajtova ili 100 bajtova (dataSize). Ukupno, 5 miliona zapisa je svaki put upisano i pročitano u svaku tabelu. Istovremeno, 5 niti je upisano/čitano u svaku tabelu (broj niti - thNum), od kojih je svaka koristila svoj raspon ključeva (broj = 1 milion):

if (opType.equals("insert")) {
    for (Long key = count * thNum; key < count * (thNum + 1); key += 0) {
        StringBuilder sb = new StringBuilder("BEGIN BATCH ");
        for (int i = 0; i < batch; i++) {
            String value = RandomStringUtils.random(dataSize, true, true);
            sb.append("INSERT INTO ")
                    .append(tableName)
                    .append("(id, title) ")
                    .append("VALUES (")
                    .append(key)
                    .append(", '")
                    .append(value)
                    .append("');");
            key++;
        }
        sb.append("APPLY BATCH;");
        final String query = sb.toString();
        session.execute(query);
    }
} else {
    for (Long key = count * thNum; key < count * (thNum + 1); key += 0) {
        StringBuilder sb = new StringBuilder("SELECT * FROM ").append(tableName).append(" WHERE id IN (");
        for (int i = 0; i < batch; i++) {
            sb = sb.append(key);
            if (i+1 < batch)
                sb.append(",");
            key++;
        }
        sb = sb.append(");");
        final String query = sb.toString();
        ResultSet rs = session.execute(query);
    }
}

U skladu s tim, slična funkcionalnost je omogućena za HB:

Configuration conf = getConf();
HTable table = new HTable(conf, keyspace + ":" + tableName);
table.setAutoFlush(false, false);
List<Get> lGet = new ArrayList<>();
List<Put> lPut = new ArrayList<>();
byte[] cf = Bytes.toBytes("cf");
byte[] qf = Bytes.toBytes("value");
if (opType.equals("insert")) {
    for (Long key = count * thNum; key < count * (thNum + 1); key += 0) {
        lPut.clear();
        for (int i = 0; i < batch; i++) {
            Put p = new Put(makeHbaseRowKey(key));
            String value = RandomStringUtils.random(dataSize, true, true);
            p.addColumn(cf, qf, value.getBytes());
            lPut.add(p);
            key++;
        }
        table.put(lPut);
        table.flushCommits();
    }
} else {
    for (Long key = count * thNum; key < count * (thNum + 1); key += 0) {
        lGet.clear();
        for (int i = 0; i < batch; i++) {
            Get g = new Get(makeHbaseRowKey(key));
            lGet.add(g);
            key++;
        }
        Result[] rs = table.get(lGet);
    }
}

Budući da u HB klijent mora voditi računa o ravnomjernoj distribuciji podataka, ključna funkcija soljenja je izgledala ovako:

public static byte[] makeHbaseRowKey(long key) {
    byte[] nonSaltedRowKey = Bytes.toBytes(key);
    CRC32 crc32 = new CRC32();
    crc32.update(nonSaltedRowKey);
    long crc32Value = crc32.getValue();
    byte[] salt = Arrays.copyOfRange(Bytes.toBytes(crc32Value), 5, 7);
    return ArrayUtils.addAll(salt, nonSaltedRowKey);
}

Sada najzanimljiviji dio - rezultati:

Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke

Ista stvar u obliku grafikona:

Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke

Prednost HB-a je toliko iznenađujuća da postoji sumnja da postoji neka vrsta uskog grla u podešavanju CS-a. Međutim, guglanje i traženje najočiglednijih parametara (kao što su concurrent_writes ili memtable_heap_space_in_mb) nije ubrzalo stvari. U isto vrijeme, trupci su čisti i ništa ne psuju.

Podaci su ravnomjerno raspoređeni po čvorovima, statistika iz svih čvorova je bila približno ista.

Ovako izgleda tabela statistike iz jednog od čvorovaKljučni prostor: ks
Broj čitanja: 9383707
Latencija čitanja: 0.04287025042448576 ms
Broj pisanja: 15462012
Latencija pisanja: 0.1350068438699957 ms
Ispiranje na čekanju: 0
Tabela: t1
SST broj tablica: 16
Korišteni prostor (uživo): 148.59 MiB
Iskorišćeni prostor (ukupno): 148.59 MiB
Prostor koji koriste snimci (ukupno): 0 bajtova
Iskorišćena memorija van hrpe (ukupno): 5.17 MiB
SSTable omjer kompresije: 0.5720989576459437
Broj particija (procjena): 3970323
Memtable broj ćelija: 0
Memtable veličina podataka: 0 bajtova
Korištena memorija izvan hrpe Memtable: 0 bajtova
Memtable broj prekidača: 5
Lokalni broj čitanja: 2346045
Lokalno kašnjenje čitanja: NaN ms
Lokalni broj pisanja: 3865503
Lokalno kašnjenje pisanja: NaN ms
Ispiranja na čekanju: 0
Postotak popravljenih: 0.0
Lažni pozitivni rezultati filtera Bloom: 25
Floom filter false ratio: 0.00000
Iskorišten prostor za Bloom filter: 4.57 MiB
Bloom filter za iskorišćenu memoriju hrpe: 4.57 MiB
Sažetak indeksa od korištene memorije gomile: 590.02 KiB
Kompresija metapodataka izvan memorije gomile korištena: 19.45 KiB
Minimalni bajtovi sabijene particije: 36
Maksimalni broj bajtova sabijene particije: 42
Sabijeni srednji bajtovi particije: 42
Prosjek živih ćelija po krišku (zadnjih pet minuta): NaN
Maksimalan broj živih ćelija po komadu (zadnjih pet minuta): 0
Prosječan broj nadgrobnih spomenika po komadu (zadnjih pet minuta): NaN
Maksimalan broj nadgrobnih spomenika po komadu (zadnjih pet minuta): 0
Ispuštene mutacije: 0 bajtova

Pokušaj smanjenja veličine serije (čak i slanje pojedinačno) nije imao efekta, samo se pogoršavao. Moguće je da je to zaista maksimalna performansa za CS, budući da su rezultati dobijeni za CS slični onima dobijenim za DataStax - oko stotine hiljada operacija u sekundi. Osim toga, ako pogledamo korištenje resursa, vidjet ćemo da CS koristi mnogo više CPU-a i diskova:

Bitka dva yakozuna, ili Cassandra vs HBase. Iskustvo tima Sberbanke
Na slici je prikazano korištenje tokom izvođenja svih testova u nizu za obje baze podataka.

Što se tiče HB-ove moćne prednosti čitanja. Ovdje možete vidjeti da je za obje baze podataka iskorištenost diska tokom čitanja izuzetno niska (testovi čitanja su završni dio ciklusa testiranja za svaku bazu podataka, na primjer za CS to je od 15:20 do 15:40). U slučaju HB-a, razlog je jasan - većina podataka visi u memoriji, u memstoru, a neki su keširani u blockcache. Što se tiče CS-a, nije baš jasno kako radi, ali recikliranje diska takođe nije vidljivo, ali za svaki slučaj pokušano je da se omogući keš row_cache_size_in_mb = 2048 i postavi keširanje = {'keys': 'SVE', 'rows_per_partition': ' 2000000'}, ali to je još malo pogoršalo situaciju.

Također je vrijedno još jednom spomenuti važnu tačku o broju regija u HB. U našem slučaju, vrijednost je navedena kao 64. Ako je smanjite i učinite jednakom, na primjer, 4, tada pri čitanju brzina pada za 2 puta. Razlog je taj što će se memstor brže puniti i fajlovi će se češće ispirati, a prilikom čitanja će biti potrebno obraditi više fajlova, što je za HB prilično komplikovana operacija. U stvarnim uslovima, ovo se može tretirati razmišljanjem kroz strategiju prethodnog razdvajanja i kompaktifikacije, posebno koristimo uslužni program koji sam pisao koji sakuplja smeće i kompresuje HFiles konstantno u pozadini. Sasvim je moguće da su za DataStax testove dodijelili samo 1 regiju po tabeli (što nije tačno) i to bi donekle razjasnilo zašto je HB bio toliko inferioran u njihovim testovima čitanja.

Iz ovoga se izvlače sljedeći preliminarni zaključci. Pod pretpostavkom da tokom testiranja nisu napravljene veće greške, onda Kasandra izgleda kao kolos sa stopalima od gline. Tačnije, dok balansira na jednoj nozi, kao na slici na početku članka, pokazuje relativno dobre rezultate, ali u borbi pod istim uslovima gubi direktno. Istovremeno, uzimajući u obzir nisku iskorišćenost CPU-a na našem hardveru, naučili smo da postavimo dva RegionServer HB-a po hostu i na taj način udvostručili performanse. One. Uzimajući u obzir iskorišćenost resursa, situacija za CS je još žalosnija.

Naravno, ovi testovi su prilično sintetički i količina podataka koja je ovdje korištena je relativno skromna. Moguće je da bi, kada bismo prešli na terabajte, situacija bila drugačija, ali dok za HB možemo učitati terabajte, za CS se to pokazalo problematičnim. Često je izbacivao OperationTimedOutException čak i kod ovih volumena, iako su parametri za čekanje odgovora već nekoliko puta povećani u odnosu na zadane.

Nadam se da ćemo zajedničkim snagama pronaći uska grla CS-a i ako to možemo ubrzati, onda ću na kraju posta svakako dodati podatke o konačnim rezultatima.

UPD: Zahvaljujući savjetima drugova, uspio sam ubrzati čitanje. Bio:
159 operacija (644 stola, 4 streamova, serija 5).
Dodao:
.withLoadBalancingPolicy(nova TokenAwarePolicy(DCAwareRoundRobinPolicy.builder().build()))
I poigrao sam se sa brojem niti. Rezultat je sljedeći:
4 stola, 100 niti, serija = 1 (komad po komad): 301 operacija
4 tabele, 100 niti, serija = 10: 447 operacija
4 tabele, 100 niti, serija = 100: 625 operacija

Kasnije ću primijeniti druge savjete za podešavanje, pokrenuti cijeli ciklus testiranja i dodati rezultate na kraju posta.

izvor: www.habr.com

Dodajte komentar