2016-09-10 2 views
0

Ich habe ein Problem mit der Skalierbarkeit Cassandra Datenbank. Trotz der Vergrößerung der Anzahl der Knoten von 2 bis zu 8, wächst die Leistung der Datenbank nicht.Cassandra Mangel an Scalability

Cassandra Version: 3.7 
Cassandra Hardware x8: 1vCPU 2.5 Ghz, 900 MB RAM, SSD DISK 20GB, 10 Gbps LAN 
Benchmark Hardware x1: 16vCPU 2.5 GHz, 8 GB RAM, SSD DISK 5GB, 10 Gbps LAN 

Standardeinstellungen wurden in cassandra.yaml geändert:

cluster_name: 'tst' 
seeds: "192.168.0.101,192.168.0.102,...108" 
listen_address: 192.168.0.xxx 
endpoint_snitch: GossipingPropertyFileSnitch 
rpc_address: 192.168.0.xxx 
concurrent_reads: 8 
concurrent_writes: 8 
concurrent_counter_writes: 8 

Schlüsselraum:

create keyspace tst WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : '2' }; 

Beispieltabelle

CREATE TABLE shares (
    c1 int PRIMARY KEY, 
    c2 varchar, 
    c3 int, 
    c4 int, 
    c5 int, 
    c6 varchar, 
    c7 int 
); 

Exemplarische Abfrage in Tests verwendet:

INSERT INTO shares (c1, c1, c3, c4, c5, c6, c7) VALUES (%s, '%s', %s, %s, %s, '%s', %s) 

Für die Verbindung mit der Basis verwende ich https://github.com/datastax/java-driver. In Multi-Threads verwende ich eines der Cluster-Objekte und eines der Session-Objekte entsprechend den Anweisungen. Anschluss:

PoolingOptions poolingOptions = new PoolingOptions(); 
poolingOptions.setConnectionsPerHost(HostDistance.LOCAL, 5, 300); 
poolingOptions.setCoreConnectionsPerHost(HostDistance.LOCAL, 10); 
poolingOptions.setPoolTimeoutMillis(5000); 
QueryOptions queryOptions = new QueryOptions(); 
queryOptions.setConsistencyLevel(ConsistencyLevel.QUORUM); 

Builder builder = Cluster.builder(); 
builder.withPoolingOptions(poolingOptions); 
builder.withQueryOptions(queryOptions); 
builder.withLoadBalancingPolicy(new RoundRobinPolicy()); 
this.setPoints(builder); // here all of the nodes are added 
Cluster cluster = builder.build() 

Code of query:

public ResultSet execute(String query) { 
ResultSet result = this.session.execute(query); 
return result; 
} 

Während der Testarbeit, mit der Erinnerung an alle Knoten beträgt 80%, und die CPU 100%. Ich bin überrascht von Verbindungen in Monitor (zu niedrig ist):

[2016-09-10 09:39:51.537] /192.168.0.102:9042 connections=10, current load=62, max load=10240 
[2016-09-10 09:39:51.556] /192.168.0.103:9042 connections=10, current load=106, max load=10240 
[2016-09-10 09:39:51.556] /192.168.0.104:9042 connections=10, current load=104, max load=10240 
[2016-09-10 09:39:51.556] /192.168.0.101:9042 connections=10, current load=196, max load=10240 
[2016-09-10 09:39:56.467] /192.168.0.102:9042 connections=10, current load=109, max load=10240 
[2016-09-10 09:39:56.467] /192.168.0.103:9042 connections=10, current load=107, max load=10240 
[2016-09-10 09:39:56.467] /192.168.0.104:9042 connections=10, current load=115, max load=10240 
[2016-09-10 09:39:56.468] /192.168.0.101:9042 connections=10, current load=169, max load=10240 
[2016-09-10 09:40:01.468] /192.168.0.102:9042 connections=10, current load=113, max load=10240 
[2016-09-10 09:40:01.468] /192.168.0.103:9042 connections=10, current load=84, max load=10240 
[2016-09-10 09:40:01.468] /192.168.0.104:9042 connections=10, current load=92, max load=10240 
[2016-09-10 09:40:01.469] /192.168.0.101:9042 connections=10, current load=205, max load=10240 

-Code des Monitors: https://github.com/datastax/java-driver/tree/3.0/manual/pooling#monitoring-and-tuning-the-pool

Ich versuche, die Skalierbarkeit von wenigen NoSQL-Datenbanken zu testen. Im Falle von Redis Base war es lineare Skalierbarkeit, hier ist sie überhaupt nicht und ich weiß nicht warum. Danke für Ihre Hilfe!

+0

Welche Werte haben Sie für Ihren Partitionsschlüssel? Wie gut werden die Daten verteilt? Cassandra verteilt Daten durch Berechnung eines Hashs auf dem Primärschlüssel. Wenn alle Ihre Daten eine kleine Anzahl von PK-Werten aufweisen, spielt es keine Rolle, wie viele Server Sie verwenden. – riwalk

Antwort

3

1 GB RAM auf jeder Maschine ist ein sehr niedriges Ziel. Dies könnte zu viel GC-Druck verursachen. Überprüfen Sie Ihr Protokoll, um die GC-Aktivität zu sehen, und versuchen Sie zu verstehen, ob diese 100% ige CPU-Obergrenze durch JVM GC'ing verursacht wird.

Eine weitere Eigenart: Wie viele Threads laufen auf jeder Maschine? Wenn Sie versuchen, mit diesem Code (Code) zu skalieren:

Code of query:

public ResultSet execute(String query) { 
ResultSet result = this.session.execute(query); 
return result; 
} 

dann werden Sie nicht sehr weit gehen. Synchrone Abfragen sind hoffnungslos langsam. Selbst wenn Sie versuchen, mehr Threads zu verwenden, dann könnte 1 GB RAM (ich weiß es bereits ...) zu niedrig sein ... Sie sollten wahrscheinlich Async-Abfragen schreiben, sowohl für den Ressourcenverbrauch als auch für die Skalierbarkeit.

+0

Danke! Ich benutze 1000 Threads in Benchmark. Wenn ich eine asynchrone Verbindung verwende, wie überprüfe ich den Wert von Abfragen in einem Teil der Zeit? – Sannin

+0

1000 Threads sind wahrscheinlich zu viele ... Bleiben Sie mit 2x vCPU Threads (also 32 Threads in Ihrem Fall) und gehen Sie den asynchronen Weg. Sie werden sie später erhöhen. Normalerweise sammeln Sie eine Liste von 'ResultSetFuture' Futures-Objekten.Wenn Sie ** Ihre ** maximale Anzahl an Inflight-Abfragen sammeln (zunächst 1000), warten Sie, bis alle beendet sind, so dass Sie einen gewissen Gegendruck anwenden und Ihren Cluster nicht unter Stress setzen. Sie können Callbacks auch für Futures in registrieren Falls Sie diesen Stil bevorzugen. Sehen Sie sich http://www.datastax.com/dev/blog/java-driver-async-queries als Beispiel an. – xmas79

Verwandte Themen