Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank

Ito ay hindi kahit isang biro, tila ang partikular na larawang ito ay pinakatumpak na sumasalamin sa kakanyahan ng mga database na ito, at sa huli ay magiging malinaw kung bakit:

Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank

Ayon sa DB-Engines Ranking, ang dalawang pinakasikat na NoSQL columnar database ay ang Cassandra (simula dito CS) at HBase (HB).

Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank

Sa pamamagitan ng kalooban ng kapalaran, ang aming data loading management team sa Sberbank ay mayroon na matagal na at gumagana nang malapit sa HB. Sa panahong ito, pinag-aralan naming mabuti ang mga kalakasan at kahinaan nito at natutunan namin kung paano ito lutuin. Gayunpaman, ang pagkakaroon ng isang alternatibo sa anyo ng CS ay palaging nagpipilit sa amin na pahirapan ang aming sarili nang kaunti sa mga pagdududa: gumawa ba kami ng tamang pagpili? Bukod dito, ang mga resulta paghahambing, na isinagawa ng DataStax, sinabi nila na ang CS ay madaling talunin ang HB sa halos isang pagdurog na marka. Sa kabilang banda, ang DataStax ay isang interesadong partido, at hindi mo dapat kunin ang kanilang salita para dito. Nalito din kami sa medyo maliit na halaga ng impormasyon tungkol sa mga kondisyon ng pagsubok, kaya nagpasya kaming alamin sa aming sarili kung sino ang hari ng BigData NoSql, at ang mga resulta na nakuha ay naging napaka-interesante.

Gayunpaman, bago lumipat sa mga resulta ng mga pagsubok na isinagawa, kinakailangan upang ilarawan ang mga makabuluhang aspeto ng mga pagsasaayos ng kapaligiran. Ang katotohanan ay ang CS ay maaaring gamitin sa isang mode na nagpapahintulot sa pagkawala ng data. Yung. ito ay kapag ang isang server lamang (node) ay responsable para sa data ng isang tiyak na susi, at kung sa ilang kadahilanan ay nabigo ito, kung gayon ang halaga ng susi na ito ay mawawala. Para sa maraming mga gawain hindi ito kritikal, ngunit para sa sektor ng pagbabangko ito ang pagbubukod sa halip na ang panuntunan. Sa aming kaso, mahalagang magkaroon ng ilang kopya ng data para sa maaasahang imbakan.

Samakatuwid, tanging ang CS operating mode sa triple replication mode ang isinasaalang-alang, i.e. Ang paglikha ng casespace ay isinagawa gamit ang mga sumusunod na parameter:

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

Susunod, mayroong dalawang paraan upang matiyak ang kinakailangang antas ng pagkakapare-pareho. Pangkalahatang tuntunin:
NW + NR > RF

Na nangangahulugan na ang bilang ng mga kumpirmasyon mula sa mga node kapag nagsusulat (NW) kasama ang bilang ng mga kumpirmasyon mula sa mga node kapag nagbabasa (NR) ay dapat na mas malaki kaysa sa replication factor. Sa aming kaso, RF = 3, na nangangahulugang ang mga sumusunod na pagpipilian ay angkop:
2 + 2 > 3
3 + 1 > 3

Dahil ito ay pangunahing mahalaga para sa amin na iimbak ang data bilang mapagkakatiwalaan hangga't maaari, ang 3+1 na pamamaraan ay pinili. Bilang karagdagan, gumagana ang HB sa isang katulad na prinsipyo, i.e. magiging mas patas ang ganitong paghahambing.

Dapat pansinin na ang DataStax ay kabaligtaran sa kanilang pag-aaral, itinakda nila ang RF = 1 para sa parehong CS at HB (para sa huli sa pamamagitan ng pagbabago ng mga setting ng HDFS). Ito ay isang talagang mahalagang aspeto dahil ang epekto sa pagganap ng CS sa kasong ito ay malaki. Halimbawa, ipinapakita ng larawan sa ibaba ang pagtaas sa oras na kinakailangan para mag-load ng data sa CS:

Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank

Dito makikita natin ang mga sumusunod: mas maraming nakikipagkumpitensyang thread ang sumulat ng data, mas tumatagal ito. Ito ay natural, ngunit mahalaga na ang pagkasira ng pagganap para sa RF=3 ay makabuluhang mas mataas. Sa madaling salita, kung magsusulat tayo ng 4 thread sa 5 na talahanayan bawat isa (20 sa kabuuan), pagkatapos ay mawawala ang RF=3 ng halos 2 beses (150 segundo para sa RF=3 kumpara sa 75 para sa RF=1). Ngunit kung dagdagan natin ang load sa pamamagitan ng paglo-load ng data sa 8 table na may 5 thread bawat isa (40 sa kabuuan), ang pagkawala ng RF=3 ay 2,7 beses na (375 seconds versus 138).

Marahil ito ay bahagyang sikreto ng matagumpay na pagsusuri sa pag-load na isinagawa ng DataStax para sa CS, dahil para sa HB sa aming kinatatayuan ang pagbabago ng replication factor mula 2 hanggang 3 ay walang epekto. Yung. ang mga disk ay hindi ang HB bottleneck para sa aming configuration. Gayunpaman, mayroong maraming iba pang mga pitfalls dito, dahil ito ay dapat tandaan na ang aming bersyon ng HB ay bahagyang na-patched at tweaked, ang mga kapaligiran ay ganap na naiiba, atbp. Kapansin-pansin din na baka hindi ko lang alam kung paano ihanda ang CS nang tama at may ilang mas epektibong paraan para gawin ito, at sana ay malaman natin sa mga komento. Ngunit una sa lahat.

Ang lahat ng mga pagsubok ay isinagawa sa isang hardware cluster na binubuo ng 4 na server, bawat isa ay may sumusunod na configuration:

CPU: Xeon E5-2680 v4 @ 2.40GHz 64 na mga thread.
Mga disk: 12 piraso ng SATA HDD
bersyon ng java: 1.8.0_111

Bersyon ng CS: 3.11.5

cassandra.yml na mga parameternum_tokens: 256
hinted_handoff_enabled: totoo
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
authenticator: AllowAllAuthenticator
authorizer: AllowAllAuthorizer
role_manager: CassandraRoleManager
roles_validity_in_ms: 2000
permissions_validity_in_ms: 2000
credentials_validity_in_ms: 2000
partitioner: org.apache.cassandra.dht.Murmur3Partitioner
data_file_directories:
- /data1/cassandra/data # bawat direktoryo ng dataN ay isang hiwalay na 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: false
disk_failure_policy: huminto
commit_failure_policy: huminto
prepared_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: pana-panahon
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
mga parameter:
β€” buto: "*,*"
concurrent_reads: 256 # tried 64 - walang napansing pagkakaiba
concurrent_writes: 256 # tried 64 - walang napansing pagkakaiba
concurrent_counter_writes: 256 # tried 64 - walang napansing pagkakaiba
concurrent_materialized_view_writes: 32
memtable_heap_space_in_mb: 2048 # sinubukan 16 GB - ito ay mas mabagal
memtable_allocation_type: heap_buffers
index_summary_capacity_in_mb:
index_summary_resize_interval_in_minutes: 60
trickle_fsync: mali
trickle_fsync_interval_in_kb: 10240
storage_port: 7000
ssl_storage_port: 7001
listen_address: *
broadcast_address: *
listen_on_broadcast_address: totoo
internode_authenticator: org.apache.cassandra.auth.AllowAllInternodeAuthenticator
start_native_transport: totoo
native_transport_port: 9042
start_rpc: totoo
rpc_address: *
rpc_port: 9160
rpc_keepalive: totoo
rpc_server_type: sync
thrift_framed_transport_size_in_mb: 15
incremental_backups: false
snapshot_before_compaction: false
auto_snapshot: totoo
column_index_size_in_kb: 64
column_index_cache_size_in_kb: 2
concurrent_compactors: 4
compaction_throughput_mb_per_sec: 1600
sstable_preemptive_open_interval_in_mb: 50
read_request_timeout_in_ms: 100000
range_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: false
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: wala
client_encryption_options:
pinagana: false
internode_compression: dc
inter_dc_tcp_nodelay: mali
tracetype_query_ttl: 86400
tracetype_repair_ttl: 604800
enable_user_defined_functions: false
enable_scripted_user_defined_functions: false
windows_timer_interval: 1
transparent_data_encryption_options:
pinagana: false
tombstone_warning_threshold: 1000
lapida_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: mali
enable_materialized_views: totoo
enable_sasi_indexes: totoo

Mga Setting ng GC:

### Mga Setting ng CMS-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=1
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSWaitDuration=10000
-XX:+CMSParallelInitialMarkEnabled
-XX:+CMSEdenChunksRecordAlways
-XX:+CMSClassUnloadingEnabled

Ang memorya ng jvm.options ay inilaan ng 16Gb (sinubukan din namin ang 32 Gb, walang pagkakaiba ang napansin).

Ang mga talahanayan ay nilikha gamit ang utos:

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

Bersyon ng HB: 1.2.0-cdh5.14.2 (sa klase org.apache.hadoop.hbase.regionserver.HRegion hindi namin isinama ang MetricsRegion na humantong sa GC noong higit sa 1000 ang bilang ng mga rehiyon sa RegionServer)

Mga hindi default na parameter ng HBasezookeeper.session.timeout: 120000
hbase.rpc.timeout: 2 minuto
hbase.client.scanner.timeout.period: 2 minuto (mga)
hbase.master.handler.count: 10
hbase.regionserver.lease.period, hbase.client.scanner.timeout.period: 2 minuto (mga)
hbase.regionserver.handler.count: 160
hbase.regionserver.metahandler.count: 30
hbase.regionserver.logroll.period: 4 na oras
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: (mga) araw
HBase Service Advanced Configuration Snippet (Safety Valve) para sa 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
Mga Opsyon sa Configuration ng Java para sa HBase RegionServer:
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSIinitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=256m
hbase.snapshot.master.timeoutMillis: 2 minuto (mga)
hbase.snapshot.region.timeout: 2 minuto (mga)
hbase.snapshot.master.timeout.millis: 2 minuto (mga)
HBase REST Server Max na Laki ng Log: 100 MiB
Pinakamataas na Log File Backup ng HBase REST Server: 5
HBase Thrift Server Max na Laki ng Log: 100 MiB
Pinakamataas na Log File Backup ng HBase Thrift Server: 5
Master Max na Laki ng Log: 100 MiB
Master Maximum Log File Backup: 5
RegionServer Max na Laki ng Log: 100 MiB
Pinakamataas na Log File Backup ng RegionServer: 5
HBase Active Master Detection Window: 4 minuto (mga)
dfs.client.hedged.read.threadpool.size: 40
dfs.client.hedged.read.threshold.millis: 10 millisecond(s)
hbase.rest.threads.min: 8
hbase.rest.threads.max: 150
Maximum Process File Descriptors: 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
Mga Thread ng Region Mover: 6
Sukat ng Java Heap ng Client sa Bytes: 1 GiB
HBase REST Server Default na Pangkat: 3 GiB
HBase Thrift Server Default Group: 3 GiB
Laki ng Java Heap ng HBase Master sa Bytes: 16 GiB
Laki ng Java Heap ng HBase RegionServer sa Bytes: 32 GiB

+ZooKeeper
maxClientCnxns: 601
maxSessionTimeout: 120000
Paglikha ng mga talahanayan:
hbase org.apache.hadoop.hbase.util.RegionSplitter ns:t1 UniformSplit -c 64 -f cf
baguhin ang 'ns:t1', {NAME => 'cf', DATA_BLOCK_ENCODING => 'FAST_DIFF', COMPRESSION => 'GZ'}

Mayroong isang mahalagang punto dito - ang paglalarawan ng DataStax ay hindi nagsasabi kung gaano karaming mga rehiyon ang ginamit upang lumikha ng mga talahanayan ng HB, bagama't ito ay kritikal para sa malalaking volume. Samakatuwid, para sa mga pagsubok, napili ang dami = 64, na nagbibigay-daan sa pag-iimbak ng hanggang 640 GB, i.e. katamtamang laki ng mesa.

Sa oras ng pagsubok, ang HBase ay mayroong 22 libong mga talahanayan at 67 libong mga rehiyon (ito ay nakamamatay para sa bersyon 1.2.0 kung hindi para sa patch na binanggit sa itaas).

Ngayon para sa code. Dahil hindi malinaw kung aling mga pagsasaayos ang mas kapaki-pakinabang para sa isang partikular na database, isinagawa ang mga pagsubok sa iba't ibang kumbinasyon. Yung. sa ilang mga pagsubok, 4 na talahanayan ang na-load nang sabay-sabay (lahat ng 4 na node ay ginamit para sa koneksyon). Sa iba pang mga pagsubok nagtrabaho kami sa 8 iba't ibang mga talahanayan. Sa ilang mga kaso, ang laki ng batch ay 100, sa iba ay 200 (parameter ng batch - tingnan ang code sa ibaba). Ang laki ng data para sa halaga ay 10 byte o 100 bytes (dataSize). Sa kabuuan, 5 milyong talaan ang isinulat at binasa sa bawat talahanayan sa bawat oras. Kasabay nito, 5 mga thread ang isinulat/binasa sa bawat talahanayan (numero ng thread - thNum), bawat isa ay gumagamit ng sarili nitong hanay ng mga susi (bilang = 1 milyon):

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);
    }
}

Alinsunod dito, ang katulad na pag-andar ay ibinigay para sa 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);
    }
}

Dahil sa HB dapat pangalagaan ng kliyente ang pare-parehong pamamahagi ng data, ganito ang hitsura ng key salting function:

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);
}

Ngayon ang pinaka-kagiliw-giliw na bahagi - ang mga resulta:

Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank

Ang parehong bagay sa graph form:

Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank

Ang bentahe ng HB ay nakakagulat na mayroong isang hinala na mayroong ilang uri ng bottleneck sa pag-setup ng CS. Gayunpaman, hindi pinabilis ng Googling at paghahanap ng mga pinakahalatang parameter (tulad ng concurrent_writes o memtable_heap_space_in_mb). Kasabay nito, ang mga troso ay malinis at hindi nanunumpa sa anumang bagay.

Ang data ay ibinahagi nang pantay-pantay sa mga node, ang mga istatistika mula sa lahat ng mga node ay halos pareho.

Ito ang hitsura ng mga istatistika ng talahanayan mula sa isa sa mga nodeKeyspace: ks
Bilang ng Binasa: 9383707
Basahin ang Latency: 0.04287025042448576 ms
Isulat ang Bilang: 15462012
Isulat ang Latency: 0.1350068438699957 ms
Nakabinbing Flushes: 0
Talahanayan: t1
Bilang ng SSTable: 16
Space na ginamit (live): 148.59 MiB
Nagamit na espasyo (kabuuan): 148.59 MiB
Space na ginagamit ng mga snapshot (kabuuan): 0 bytes
Off heap memory na ginamit (kabuuan): 5.17 MiB
SSTable Compression Ratio: 0.5720989576459437
Bilang ng mga partisyon (pagtantiya): 3970323
Memtable na bilang ng cell: 0
Memtable na laki ng data: 0 bytes
Memtable off heap memory na ginamit: 0 bytes
Memtable na bilang ng switch: 5
Lokal na bilang ng nabasa: 2346045
Lokal na read latency: NaN ms
Lokal na bilang ng pagsusulat: 3865503
Lokal na write latency: NaN ms
Nakabinbing pag-flush: 0
Porsiyento na naayos: 0.0
Bloom filter ang mga maling positibo: 25
Bloom filter false ratio: 0.00000
Bloom filter space na ginamit: 4.57 MiB
Bloom filter off heap memory na ginamit: 4.57 MiB
Buod ng index off heap memory na ginamit: 590.02 KiB
Compression metadata off heap memory na ginamit: 19.45 KiB
Minimum na byte ng compact na partition: 36
Pinakamataas na byte ng compact na partition: 42
Compacted partition mean bytes: 42
Average na mga live na cell bawat slice (huling limang minuto): NaN
Pinakamataas na mga live na cell bawat slice (huling limang minuto): 0
Average na mga lapida sa bawat hiwa (huling limang minuto): NaN
Pinakamataas na lapida bawat hiwa (huling limang minuto): 0
Mga Nalaglag na Mutation: 0 bytes

Ang isang pagtatangka na bawasan ang laki ng batch (kahit na ipadala ito nang paisa-isa) ay walang epekto, lalo itong lumala. Posible na sa katunayan ito talaga ang pinakamataas na pagganap para sa CS, dahil ang mga resulta na nakuha para sa CS ay katulad ng nakuha para sa DataStax - mga daan-daang libong mga operasyon bawat segundo. Bilang karagdagan, kung titingnan natin ang paggamit ng mapagkukunan, makikita natin na ang CS ay gumagamit ng mas maraming CPU at mga disk:

Labanan ng dalawang yakozuna, o Cassandra vs HBase. Karanasan ng koponan ng Sberbank
Ipinapakita ng figure ang paggamit sa panahon ng pagpapatakbo ng lahat ng mga pagsubok sa isang hilera para sa parehong mga database.

Tungkol sa makapangyarihang bentahe sa pagbabasa ng HB. Dito makikita mo na para sa parehong mga database, ang paggamit ng disk sa panahon ng pagbabasa ay napakababa (ang mga pagsusulit sa pagbasa ay ang huling bahagi ng ikot ng pagsubok para sa bawat database, halimbawa para sa CS ito ay mula 15:20 hanggang 15:40). Sa kaso ng HB, malinaw ang dahilan - karamihan sa data ay nakabitin sa memorya, sa memstore, at ang ilan ay naka-cache sa blockcache. Tulad ng para sa CS, hindi masyadong malinaw kung paano ito gumagana, ngunit ang pag-recycle ng disk ay hindi rin nakikita, ngunit kung sakali, isang pagtatangka ay ginawa upang paganahin ang cache row_cache_size_in_mb = 2048 at itakda ang caching = {'keys': 'ALL', 'rows_per_partition': ' 2000000'}, ngunit lalo itong nagpalala.

Ito rin ay nagkakahalaga ng pagbanggit muli ng isang mahalagang punto tungkol sa bilang ng mga rehiyon sa HB. Sa aming kaso, ang halaga ay tinukoy bilang 64. Kung bawasan mo ito at gagawin itong katumbas ng, halimbawa, 4, pagkatapos ay kapag nagbabasa, ang bilis ay bumaba ng 2 beses. Ang dahilan ay mas mabilis na mapupuno ang memstore at mas madalas na ma-flush ang mga file at kapag nagbabasa, mas maraming file ang kailangang iproseso, na isang medyo kumplikadong operasyon para sa HB. Sa totoong mga kondisyon, maaari itong gamutin sa pamamagitan ng pag-iisip sa pamamagitan ng diskarte sa presplitting at compactification; lalo na, gumagamit kami ng self-written utility na kumukolekta ng basura at patuloy na nag-compress ng HFiles sa background. Posible na para sa mga pagsubok sa DataStax ay naglaan lamang sila ng 1 rehiyon sa bawat talahanayan (na hindi tama) at ito ay medyo magpapaliwanag kung bakit ang HB ay napakababa sa kanilang mga pagsusulit sa pagbabasa.

Ang mga sumusunod na paunang konklusyon ay nakuha mula dito. Sa pag-aakalang walang malalaking pagkakamali ang nagawa sa panahon ng pagsubok, kung gayon si Cassandra ay mukhang isang colossus na may mga paa ng luad. Mas tiyak, habang siya ay nagbabalanse sa isang binti, tulad ng sa larawan sa simula ng artikulo, nagpapakita siya ng medyo mahusay na mga resulta, ngunit sa isang labanan sa ilalim ng parehong mga kondisyon ay natalo siya. Kasabay nito, isinasaalang-alang ang mababang paggamit ng CPU sa aming hardware, natutunan naming magtanim ng dalawang RegionServer HB bawat host at sa gayon ay nadoble ang pagganap. Yung. Kung isasaalang-alang ang paggamit ng mga mapagkukunan, ang sitwasyon para sa CS ay mas nakalulungkot.

Siyempre, ang mga pagsubok na ito ay medyo sintetiko at ang dami ng data na ginamit dito ay medyo katamtaman. Posible na kung lumipat tayo sa terabytes, iba ang sitwasyon, ngunit habang para sa HB maaari tayong mag-load ng terabytes, para sa CS ito ay naging problema. Madalas itong naghagis ng OperationTimedOutException kahit na sa mga volume na ito, kahit na ang mga parameter para sa paghihintay para sa isang tugon ay nadagdagan nang ilang beses kumpara sa mga default.

Umaasa ako na sa pamamagitan ng magkasanib na pagsisikap ay makikita natin ang mga bottleneck ng CS at kung mapapabilis natin ito, pagkatapos ay sa dulo ng post ay tiyak na magdagdag ako ng impormasyon tungkol sa mga huling resulta.

UPD: Salamat sa payo ng mga kasama, napabilis ko ang pagbabasa. ay:
159 ops (644 na talahanayan, 4 stream, batch 5).
Idinagdag ni:
.withLoadBalancingPolicy(new TokenAwarePolicy(DCAwareRoundRobinPolicy.builder().build()))
At naglaro ako sa dami ng thread. Ang resulta ay ang mga sumusunod:
4 na talahanayan, 100 thread, batch = 1 (pira-piraso): 301 ops
4 na talahanayan, 100 thread, batch = 10: 447 ops
4 na talahanayan, 100 thread, batch = 100: 625 ops

Mamaya ay maglalapat ako ng iba pang mga tip sa pag-tune, magpatakbo ng isang buong ikot ng pagsubok at idagdag ang mga resulta sa dulo ng post.

Pinagmulan: www.habr.com

Magdagdag ng komento