2016-10-30 4 views
0

Ich habe angefangen, Casandra seit den letzten paar Tagen zu verwenden, und hier ist, was ich versuche zu tun.Cassandra Lesen/Schreiben Leistung - Hohe CPU

Ich habe etwa 2 Millionen Objekte, die Profile von Benutzern pflegen. Ich konvertiere diese Objekte in json, komprimiere und speichere sie in einer BLOB-Spalte. Die durchschnittliche komprimierte JSON-Größe beträgt etwa 10 KB. Dies ist, wie meine Tabelle in cassandra aussieht,

Tabelle:

dev.userprofile (uid varchar primary key, profile blob); 

Auswahlabfrage: wählen Profil von dev.userprofile wo uid = '';

Aktualisierungsabfrage:

update dev.userprofile set profile='<bytebuffer>' where uid = '<uid>' 

Jede Stunde, ich Ereignisse aus einer Warteschlange, die ich mein Benutzerprofil Objekt anwenden. Jedes Ereignis entspricht einem Benutzerprofilobjekt. Ich bekomme ungefähr 1 Million solcher Ereignisse, also muss ich etwa 1M der Benutzerprofilobjekte innerhalb kurzer Zeit aktualisieren, d. H. Das Objekt in meiner Anwendung aktualisieren, den JSON komprimieren und den Cassandra-Blob aktualisieren. Ich muss alle 1 Million Benutzerprofilobjekte vorzugsweise in wenigen Minuten aktualisieren. Aber ich merke, dass es jetzt länger dauert.

Beim Ausführen meiner Anwendung stelle ich fest, dass ich im Durchschnitt etwa 400 Profile/Sekunde aktualisieren kann. Ich sehe bereits eine Menge CPU Iowait - 70% + auf Cassandra-Instanz. Außerdem ist die Last anfänglich ziemlich hoch um 16 (bei 8 VCPU-Instanz) und fällt dann auf etwa 4 ab.

Was mache ich falsch? Weil, als ich kleinere Objekte der Größe 2KB aktualisierte, bemerkte ich, dass Cassandra-Operationen/Sek. Viel schneller sind. Ich konnte ungefähr 3000 Ops/Sek. Erreichen. Irgendwelche Gedanken darüber, wie ich die Leistung verbessern sollte?

<dependency> 
    <groupId>com.datastax.cassandra</groupId> 
    <artifactId>cassandra-driver-core</artifactId> 
    <version>3.1.0</version> 
</dependency> 
<dependency> 
    <groupId>com.datastax.cassandra</groupId> 
    <artifactId>cassandra-driver-extras</artifactId> 
    <version>3.1.0</version> 
</dependency> 

Ich habe nur einen Knoten von cassandra Einrichtung innerhalb einer m4.2xlarge aws Instanz zum Testen

Single node Cassandra instance 
m4.2xlarge aws ec2 
500 GB General Purpose (SSD) 
IOPS - 1500/10000 

nodetool cfstats Ausgang

Keyspace: dev 
    Read Count: 688795 
    Read Latency: 27.280683695439137 ms. 
    Write Count: 688780 
    Write Latency: 0.010008401811899301 ms. 
    Pending Flushes: 0 
     Table: userprofile 
     SSTable count: 9 
     Space used (live): 32.16 GB 
     Space used (total): 32.16 GB 
     Space used by snapshots (total): 0 bytes 
     Off heap memory used (total): 13.56 MB 
     SSTable Compression Ratio: 0.9984539538554672 
     Number of keys (estimate): 2215817 
     Memtable cell count: 38686 
     Memtable data size: 105.72 MB 
     Memtable off heap memory used: 0 bytes 
     Memtable switch count: 6 
     Local read count: 688807 
     Local read latency: 29.879 ms 
     Local write count: 688790 
     Local write latency: 0.012 ms 
     Pending flushes: 0 
     Bloom filter false positives: 47 
     Bloom filter false ratio: 0.00003 
     Bloom filter space used: 7.5 MB 
     Bloom filter off heap memory used: 7.5 MB 
     Index summary off heap memory used: 2.07 MB 
     Compression metadata off heap memory used: 3.99 MB 
     Compacted partition minimum bytes: 216 bytes 
     Compacted partition maximum bytes: 370.14 KB 
     Compacted partition mean bytes: 5.82 KB 
     Average live cells per slice (last five minutes): 1.0 
     Maximum live cells per slice (last five minutes): 1 
     Average tombstones per slice (last five minutes): 1.0 
     Maximum tombstones per slice (last five minutes): 1 

nodetool cfhistograms Ausgang

Percentile SSTables  Write Latency  Read Latency Partition Size  Cell Count 
           (micros)   (micros)   (bytes) 
50%    3.00    9.89   2816.16    4768     2 
75%    3.00    11.86   43388.63    8239     2 
95%    4.00    14.24   129557.75    14237     2 
98%    4.00    20.50   155469.30    17084     2 
99%    4.00    29.52   186563.16    20501     2 
Min    0.00    1.92    61.22    216     2 
Max    5.00   74975.55  4139110.98   379022     2 

Dstat Ausgang

---load-avg--- --io/total- ---procs--- ------memory-usage----- ---paging-- -dsk/total- ---system-- ----total-cpu-usage---- -net/total- 
1m 5m 15m | read writ|run blk new| used buff cach free| in out | read writ| int csw |usr sys idl wai hiq siq| recv send 
12.8 13.9 10.6|1460 31.1 |1.0 14 0.2|9.98G 892k 21.2G 234M| 0  0 | 119M 3291k| 63k 68k| 1 1 26 72 0 0|3366k 3338k 
13.2 14.0 10.7|1458 28.4 |1.1 13 1.5|9.97G 884k 21.2G 226M| 0  0 | 119M 3278k| 61k 68k| 2 1 28 69 0 0|3396k 3349k 
12.7 13.8 10.7|1477 27.6 |0.9 11 1.1|9.97G 884k 21.2G 237M| 0  0 | 119M 3321k| 69k 72k| 2 1 31 65 0 0|3653k 3605k 
12.0 13.7 10.7|1474 27.4 |1.1 8.7 0.3|9.96G 888k 21.2G 236M| 0  0 | 119M 3287k| 71k 75k| 2 1 36 61 0 0|3807k 3768k 
11.8 13.6 10.7|1492 53.7 |1.6 12 1.2|9.95G 884k 21.2G 228M| 0  0 | 119M 6574k| 73k 75k| 2 2 32 65 0 0|3888k 3829k 

bearbeiten

Switched LeveledCompactionStrategy & deaktiviert Kompression auf sstables, ich habe nicht eine große Verbesserung sehen:

Es war ein wenig Verbesserung in profiles/sec aktualisiert. Es sind jetzt 550-600 Profile/Sek. Aber die CPU-Spitzen bleiben, d. H. Der Iowait.

gcstats

Interval (ms) Max GC Elapsed (ms)Total GC Elapsed (ms)Stdev GC Elapsed (ms) GC Reclaimed (MB)   Collections  Direct Memory Bytes 
      755960     83    3449     8   73179796264     107      -1 

dstats

---load-avg--- --io/total- ---procs--- ------memory-usage----- ---paging-- -dsk/total- ---system-- ----total-cpu-usage---- -net/total- 
1m 5m 15m | read writ|run blk new| used buff cach free| in out | read writ| int csw |usr sys idl wai hiq siq| recv send 
7.02 8.34 7.33| 220 16.6 |0.0 0 1.1|10.0G 756k 21.2G 246M| 0  0 | 13M 1862k| 11k 13k| 1 0 94 5 0 0| 0  0 
6.18 8.12 7.27|2674 29.7 |1.2 1.5 1.9|10.0G 760k 21.2G 210M| 0  0 | 119M 3275k| 69k 70k| 3 2 83 12 0 0|3906k 3894k 
5.89 8.00 7.24|2455 314 |0.6 5.7 0|10.0G 760k 21.2G 225M| 0  0 | 111M 39M| 68k 69k| 3 2 51 44 0 0|3555k 3528k 
5.21 7.78 7.18|2864 27.2 |2.6 3.2 1.4|10.0G 756k 21.2G 266M| 0  0 | 127M 3284k| 80k 76k| 3 2 57 38 0 0|4247k 4224k 
4.80 7.61 7.13|2485 288 |0.1 12 1.4|10.0G 756k 21.2G 235M| 0  0 | 113M 36M| 73k 73k| 2 2 36 59 0 0|3664k 3646k 
5.00 7.55 7.12|2576 30.5 |1.0 4.6 0|10.0G 760k 21.2G 239M| 0  0 | 125M 3297k| 71k 70k| 2 1 53 43 0 0|3884k 3849k 
5.64 7.64 7.15|1873 174 |0.9 13 1.6|10.0G 752k 21.2G 237M| 0  0 | 119M 21M| 62k 66k| 3 1 27 69 0 0|3107k 3081k 

Sie könnten die CPU-Spitzen bemerken.

enter image description here

Mein Hauptanliegen iowait ist, bevor ich die Last weiter zu erhöhen. Gibt es etwas Bestimmtes, wonach ich suchen sollte? Weil 600 Profile/Sek. (D. H. 600 Lese- und Schreibvorgänge) für mich niedrig erscheinen.

+0

Wenn Sie einen Eintrag aktualisieren, müssen Sie ihn lesen, dekomprimieren, den Teil, der sich ändert, aktualisieren und dann den Datensatz komprimieren und erneut speichern. Diese Operationen hängen stark von der Größe der Einträge ab. Wenn die Geschwindigkeit nicht von der Größe der Einträge abhängig wäre, wäre etwas falsch. –

+0

Es wird nicht gelesen, bevor auf Updates geschrieben wird. –

+0

Die Select-Abfrage hinzugefügt, die ich vor dem Schreiben beim Update gelesen habe. – plspl

Antwort

1

Können Sie LeveledCompactionStrategy ausprobieren? Bei 1: 1 Lese-/Schreibvorgängen auf großen Objekten wie diesem wird die bei Leseoperationen gespeicherte E/A wahrscheinlich den Ausgaben für die teureren Komprimierungen entgegenwirken.

Wenn Sie die Daten bereits vor dem Senden komprimieren, sollten Sie die Komprimierung für die Tabelle deaktivieren. Es bricht es in 64kb Brocken, die weitgehend von nur 6 Werten dominiert werden, die nicht viel Kompression bekommen (wie in schrecklichen Kompressionsverhältnis gezeigt SSTable Compression Ratio: 0.9984539538554672).

ALTER TABLE dev.userprofile 
    WITH compaction = { 'class' : 'LeveledCompactionStrategy' } 
    AND compression = { 'sstable_compression' : '' }; 

400 Profile/Sekunde ist sehr, sehr langsam, obwohl und es kann einige Arbeit auf dem Client zu tun, die möglicherweise Engpass als auch sein könnte. Wenn Sie eine 4-Last auf einem 8-Kern-System haben, kann es sein, dass Cassandra die Dinge nicht verlangsamt. Stellen Sie sicher, dass Sie Ihre Anforderungen parallelisieren und asynchron verwenden. Das häufige Senden von Anforderungen ist ein häufiges Problem.

Mit größeren Blobs wird es Auswirkungen auf GCs haben, daher kann es hilfreich sein, sie zu überwachen und hinzuzufügen. Ich würde überrascht sein, dass 10kb-Objekte es so sehr beeinflussen, aber es ist etwas, worauf man achten sollte, und es könnte mehr JVM-Tuning erfordern.

Wenn das hilft, würde ich empfehlen, den Heap zu tunen und auf mindestens 3.7 oder die neueste Version 3.0 zu aktualisieren.

+0

danke. Ich sehe nur wenige Verbesserungen. 1) Gibt es eine Möglichkeit zu überprüfen, ob die Komprimierung wirklich ausgeschaltet ist? Beschreibung Tabelle zeigt Leerzeichen für "sstable_compression". ist es das? Auch Iowait ist nicht weit gegangen. Ich sehe die gelegentlichen CPU Spikes veröffentlicht die neue stat.s – plspl

+0

sprach zu früh. Die hohen CPU-Spitzen (Iowait) und die hohe Last bleiben immer noch. – plspl

+0

Habe gerade realisiert, dass du EBS verwendest. Es ist viel einfacher, einfach einen I2-Instanz- und Instanz-Store zu verwenden, um eine großartige Leistung zu erzielen. EBS wird mehr Hände halten müssen. Theres eine gute Präsentation mit einigen Menschen, die Erfolg hatten: http://www.slideshare.net/AmazonWebServices/bdt323-amazon-ebs-candandra-1-million-writes-per-second können Sie aktualisierte Statistiken/Histos nach LCS wechseln? schaut immer noch primär von read io.Hast du die empfohlenen Betriebssystemeinstellungen durchlaufen? https://docs.datastax.com/de/landing_page/doc/landing_page/recommendedSettingsLinux.html (auch wenn das nicht für EBS ist es ein Anfang) –