Cassandra研究報告

1基本安裝

1.1在基於RHEL的系統中安裝Cassandra

1.1.1必要條件

Ø  YUM包管理器

Ø  Root或sudo權限

Ø  JRE6或者JRE7

Ø  JNA(Java native Access)(生產環境需要) 

1.1.2步驟

Ø  安裝配置JRE(略)

Ø  添加軟件包倉庫到YUM的軟件庫

將以下內容添加進/etc/yum.repos.d/datastax.repo文件即可:

[datastax] 

name = DataStax Repo for ApacheCassandra

baseurl =http://rpm.datastax.com/community

enabled = 1

gpgcheck = 0

 Ø  安裝2.0版最新的軟件包

$ sudo yuminstall dsc20

 Ø  安裝JNA

$ sudo yuminstall jna

 經過上述步驟即安裝好了Cassandra,隨後便可對其進行配置。以此方式安裝的Cassandra會創建一個名爲cassandra的用戶,cassandra以此用戶啓動服務。

1.2在任意基於Linux的系統中安裝Cassandra

1.2.1必要條件

Ø  JRE6或者JRE7

Ø  JNA(Java native Access) (生產環境需要)

1.2.2步驟

Ø  安裝配置JRE(略)

Ø  下載Cassandra二進制 tarball

http://planetcassandra.org/Download/StartDownload頁面手工下載對應版本的Cassandra,或者通過curl -OLhttp://downloads.datastax.com/community/dsc.tar.gz命令自動下載最新的DataStaxCommunity,也可由http://cassandra.apache.org/download/頁面手工下載對應版本。

 Ø  解壓tarball

tar –xzvf dsc-cassandra-2.0.0-bin.tar.gz

根據下載的版本也可能是:tar –xzvf  apache-cassandra-2.0.0-bin.tar.gz 

 Ø  安裝配置JNA

²  下載jna.jar(https://github.com/twall/jna/ )。

²  將下載的jna.jar添加進Cassandra安裝目錄的lib目錄下或將其添加進CLASSPATH環境變量中

²  在/etc/security/limits.conf文件中加入如下行:

$USER soft memlock unlimited

$USER hard memlock unlimited

其中$USER爲運行cassandra的用戶

 Ø  創建數據目錄和日誌目錄並指定給用於運行cassandra服務的具有相應讀寫權限的用戶

$ sudo mkdir/var/lib/cassandra

$ sudo mkdir/var/log/cassandra

$ sudo chown-R  $USER: $GROUP /var/lib/cassandra

$ sudo chown-R  $USER: $GROUP /var/log/Cassandra

Cassandra配置文件中默認使用上述目錄分別作爲數據目錄和日誌目錄,可創建不同的目錄,賦予對應的權限,並在配置文件中重新指定以改變默認行爲。

 至此已安裝好了Cassandra,隨後便可對其進行配置。

1.3在其他平臺安裝Cassandra(略)

1.5通過源碼構建Cassandra(略)

2簡單配置

Cassandra的主配置文件爲cassandra.yaml,其位置隨Cassandra安裝方式不同而不同。

Ø  對於CassandraPackage安裝:/etc/cassandra/conf

Ø  對於CassandraBinary安裝:<install_location>/conf

Ø  對於DataStaxEnterprise Packaged安裝:/etc/dse/cassandra

Ø  對於DataStaxEnterpriseBinary安裝:<install_location>/resources/cassandra/conf

 配置文件中的配置參數被分爲如下幾個組

Ø  Initialization properties:控制集羣內的節點如何配置,包括節點間通訊,數據分區及複製佈置。

Ø  Global row and key caches properties:用於緩存表的參數的配置參數。

Ø  Performance tuning properties:調整性能和系統資源的利用,包括內存、磁盤I/O、CPU、讀和寫。

Ø  Binary and RPC protocol timeout properties:用於二進制協議的超時設置。

Ø  Remote procedure call tuning(RPC)properties:用於配置和調整RPCs(客戶端連接)

Ø  Fault detection properties:用於處理運行情況較差或者失敗的節點。

Ø  Automatic backup properties:用於自動化備份。

Ø  Security properties:用於服務器端和客戶端的安全設置

每個組包都含若干具體的參數(具體內容可參考:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/configuration/configCassandra_yaml_r.html

 例如,對於新安裝的Cassandra可能會修改配置文件中的下面幾個參數

Ø  data_file_directories:數據目錄,對於包方式(如deb或rpm)安裝的Cassandra,該目錄會在安裝過程中自動創建並具有正確的權限,默認位置爲/var/lib/cassandra/data。

Ø  commitlog_directory:commit log目錄,對於包方式安裝的Cassandra,該目錄會在安裝過程中自動創建並具有正確的權限,默認位置爲/var/lib/cassandra/commitlog。

Ø  saved_caches_directory:保存的緩存目錄,對於包方式安裝的Cassandra,該目錄會在安裝過程中自動創建並具有正確的權限,默認位置爲/var/lib/cassandra/saved_caches。

如果以二進制方式或源碼方式安裝Cassandra需自行創建相應目錄,賦予正確的權限。又或者不想使用默認的位置,也可以自行創建新的目錄,賦予正確的權限,並在配置文件中指定。比如:

data_file_directories:/data/cassandra/data

commitlog_directory:/data/cassandra/commitlog

saved_caches_directory:/data/cassandra/saved_caches

 另外,對於包方式安裝的Cassandra,還會在安裝過程中自動創建/var/log/cassandra目錄並賦予正確的權限。默認情況下Cassandra將其日誌寫進該目錄的system.log文件中。可通過修改log4j-server.properies文件(與cassandra.yaml位於同一目錄)中的log4j.appender.R.File來改變默認行爲,比如:log4j.appender.R.File=/data/cassandra/system.log

 還可能要修改JVM級別的參數,該部分的參數可在cassandra-env.sh文件(與cassandra.yaml位於同一目錄)中設置。

3啓動及簡單使用

3.1啓動Cassandra

對於二進制包安裝方式

Ø  執行bin/cassandra–f,前臺啓動cassandra,cassandra會將日誌輸出到標準輸出中。若沒在輸出中看到「error」、「fatal」或者類似「java stack trace」的內容表明cassandra可正常工作。可通過「Control-C「停止casandra。

Ø  執行bin/cassandra,後臺啓動cassandra。

Ø  可通過kill或pkill命令停止cassandra

 對於YUM安裝方式

Ø  執行sudoservice Cassandra start啓動cassandra

Ø  執行sudoservice Cassandra stop 停止cassandra

3.2使用cqlsh

執行bin/cqlsh,出現如下提示則表明連接成功(需python2.7):

Connected toTest Cluster at localhost:9160.

[cqlsh 4.0.0 |Cassandra 2.0.0 | CQL spec 3.1.0 | Thrift protocol 19.37.0]

Use HELP forhelp.

 可在cqlsh命令提示符下輸入help或?獲得幫助,輸入exit或quit退出cqlsh,命令默認以「;」結束。

 查看keyspace

DESCRIBEkeyspaces;

 創建keyspace

CREATEKEYSPACE mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy','replication_factor' : 2 };

 切換keyspace

USE mykeyspace;

 創建表

CREATE TABLEusers (

  user_id int PRIMARY KEY, 

  fname text, 

  lname text

);

 查看錶

DESCRIBETABLES;

 插入數據

INSERT INTOusers (user_id,  fname, lname) 

  VALUES (1745, 'john', 'smith');

INSERT INTOusers (user_id,  fname, lname) 

  VALUES (1744, 'john', 'doe');

INSERT INTOusers (user_id,  fname, lname) 

  VALUES (1746, 'john', 'smith');

 查詢數據

SELECT * FROMusers;

 建立索引後使用WHERE從句查找

CREATE INDEXON users (lname);

SELECT * FROMusers WHERE lname = 'smith';

 刪除表

DROP TABLEusers;

 至此已經擁有了單節點的Cassandra,且能夠通過cqlsh連接至cassandra並使用CQL執行操作。下面對Cassandra作進一步介紹。

4搭建集羣

4.1單數據中心集羣

4.1.1前置工作

Ø  在每個節點上裝配Cassandra

Ø  爲集羣確定名稱

Ø  獲取每個節點的IP

Ø  確定用來做種子的節點(Cassandra通過種子節點來找到彼此並瞭解環的拓撲)

Ø  確定snitch(用於確定向/從哪個數據中心和網架寫入/讀取數據。有不同的類型可選,具體參考:http://www.datastax.com/documentation/cassandra/2.0/webhelp/cassandra/architecture/architectureSnitchesAbout_c.html

4.1.2具體配置

1.假定使用以下已經安裝了Cassandra的節點配置集羣(資源有限,這裏只用兩臺機器來說明過程。真實環境下最好是有多臺機器,且一個集羣中最好有一個以上的種子)

node0192.168.83.35 (seed)

node1192.168.83.37

 2.假定節點所在機器有防火牆,注意開放Cassandra所使用的端口(相關端口可查http://www.datastax.com/documentation/cassandra/2.0/webhelp/cassandra/security/secureFireWall_r.html

 3.若Cassandra正運行則先關閉,後清除數據。

$ sudo servicecassandra stop

或者(根據安裝方式而不同)

$ ps auwx |grep cassandra

$ sudo  kill <pid>

 4.清除數據

$ sudo rm -rf/var/lib/cassandra/*

 5.修改cassandra.yaml文件中的相應內容

cluster_name:'MyDemoCluster'

num_tokens:256

seed_provider:

 - class_name:org.apache.cassandra.locator.SimpleSeedProvider

    parameters:

         - seeds:  "192.168.83.35"

listen_address:192.168.83.35

rpc_address:0.0.0.0

endpoint_snitch:SimpleSnitch

若是建立全新的還不包含數據的集羣則加上auto_bootstrap:false

 6.剩餘節點的配置與除了listen_address應當爲自身IP外,其他配置與上述相同

 7.先啓動逐個啓動seed節點,再逐個啓動剩餘節點

$ sudo servicecassandra start

或者

$ cd<install_location> 

$ bin/Cassandra

8.使用nodetoolstatus命令查看集羣是否成功運行

4.2多數據中心集羣

這裏,數據中心指的就是一組節點,與複製組是同義詞。多數據中心集羣中,數據可以在不同數據中心間自動、透明覆制。

4.2.1前置工作

與單節點集羣配置基本相同,不同的是還需要確定數據中心和網架的命名。

4.2.2具體配置

1.假定在以下已經安裝了Cassandra的節點配置集羣

node0 192.168.83.35(seed1)

node1 192.168.83.36

node2 192.168.83.37

node3 192.180.83.35(seed2)

node4 192.180.83.36

node5 192.168.83.37

2.若如防火牆,則先開放相應端口(同上)

3.若Cassandra正運行則先關閉(同上)

4.清除數據(同上)

5.修改cassandra.yaml文件中的相應內容

…同上…

endpoint_snitch:PropertyFileSnitch

若是建立全新的還不包含數據的集羣則加上auto_bootstrap:false

6.剩餘節點的配置與除了listen_address應當爲自身IP外,其他配置與上述相同

7.步驟5中指定endpoint_snitch爲PropertyFileSnitch所以要編輯對應的cassandra-topologies.properties配置文件(若endpoint_snitch指定爲GossipingPropertyFileSnitch則要編輯cassandra-rackdc.properties,指定爲YamlFileNetworkTopologySnitch則要編輯cassandra-topology.yaml)

# CassandraNode IP=Data Center:Rack

192.168.83.35=DC1:RAC1

192.168.83.36=DC2:RAC1

192.168.83.37=DC1:RAC1

192.180.83.35 =DC2:RAC1

192.180.83.36=DC1:RAC1

192.168.83.37=DC2:RAC1

之後還要爲位置的節點設置一個默認的數據中心和網架名

# default forunknown nodes

default=DC1:RAC1

8.逐個啓動種子節點,之後逐個啓動剩餘節點(同上)

9.驗證環是否成功啓動(同上)

5使用CQL

CQL:CassandraQuery Language

 激活CQL:cqlsh、DataStaxJava Driver、Thrift方法set_cql_version、Python驅動中的connect()調用。

 使用cqlsh

bin/cqlsh hostport –u username –p password

創建keyspace

keyspace爲表命名空間,指明節點中數據如何複製,一般一個應用對應一個keyspace。cassandra中的複製控制以單個keyspace爲基礎。

CREATEKEYSPACE demodb WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor': 3};

class指明覆制策略,replication_factor指明覆制的份數

 使用keyspace

USE demodb;

更新keyspace

ALTER KEYSPACEdemodb WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 2};

ALTER KEYSPACEdemodb WITH REPLICATION ={'class' : 'NetworkTopologyStrategy', 'dc1' : 3, 'dc2': 2};

之後在每個受影響的節點執行nodetoolrepair demodb

 創建表

use demodb

CREATE TABLEusers (

  user_name varchar,

  password varchar,

  gender varchar,

  session_token varchar,

  state varchar,

  birth_year bigint,

  PRIMARY KEY (user_name));

 使用複合primary key創建表

CREATE TABLEemp (

  empID int,

  deptID int,

  first_name varchar,

  last_name varchar,

  PRIMARY KEY (empID, deptID));

 插入數據

INSERT INTOemp (empID, deptID, first_name, last_name) VALUES (104, 15, 'jane', 'smith');

 查詢表(以系統表爲例)

system是Cassandra的系統庫,當前含schema_keyspaces、local、peers、schema_columns和schema_columnfamilies幾個表,分別包含keyspace信息,本地節點信息、集羣節點信息、columns信息和columnfamilies信息

use system

SELECT * from schema_keyspaces;獲取到當前節點中的eyspace

SELECT * FROMpeers獲取節點所在集羣信息

提取並排序查詢結果

SELECT * FROMemp WHERE empID IN (103,104) ORDER BY deptID DESC;

使用keyspace限定符

經常使用USE keyspacename來切換keyspace可能不方便,可使用keyspace限定符指定表所屬的keyspace,如

SELECT * fromsystem.schema_keyspaces;

可在ALTER TABLEC、REATE TABLE、DELETE、INSERT、SELECT、TRUNCATE、UPDATE中使用

 指定column的過期時間

INSERT INTOemp (empID, deptID, first_name, last_name) VALUES (105, 17, 'jane', 'smith')USING TTL 60;

其中USING TTL 60指明該條數據60秒後過期,屆時會被自動刪除。另外指定了TTL的數據columns會在compaction和repair操作中被自動刪除。指定TTL會有8字節額外開銷。

 查詢過期時間

SELECT TTL(last_name)from emp;

 更新過期時間

INSERT INTOemp (empID, deptID, first_name, last_name) VALUES (105, 17, 'miaomiao', 'han')USING TTL 3600;也即,以新的TTL重插一遍數據即可。(指定插入的整條數據的過期時間)

或者UPDATA emp USINGTTL 3600 SET last_name='han' where empid=105 and deptid=17; (指定set指明的數據的過期時間)

 查詢寫入時間

SELECTWRITETIME(first_name) from emp;可查的該數據何時被插入。

 添加columns

ALTER TABLEemp ADD address varchar;

 更改column數據類型

ALTER TABLEemp ALTER address TYPE text;

 移除數據

²  指定過期時間(同上)

²  刪除table或keyspace 

DROP TABLE table_name

DROP KEYSPACE keyspace_name;

²  刪除columns和rows

DELETE last_name FROM emp WHEREempid=104 and deptid=15;

DELETE FROM emp WHERE empid=104 anddeptid=15;

 使用collection類型

²  set類型

CREATE TABLE users (

  user_id text PRIMARY KEY,

  first_name text,

  last_name text,

  emails set<text>

);

n  INSERT INTO users (user_id, first_name, last_name, emails) VALUES('frodo','Frodo', 'Baggins', {'[email protected]', '[email protected]'});

n  UPDATE users SET emails = emails + {'[email protected]'} WHEREuser_id = 'frodo';

n  UPDATE users SET emails = emails - {'[email protected]'} WHEREuser_id = 'frodo';

n  UPDATE users SET emails = {} WHERE user_id = 'frodo';

n  DELETE emails FROM users WHERE user_id = 'frodo';

²  list類型

n  ALTER TABLE users ADD top_places list<text>;

n  UPDATE users SET top_places = [ 'rivendell', 'rohan' ] WHERE user_id= 'frodo';

n  UPDATE users SET top_places = [ 'the shire' ] + top_places WHEREuser_id = 'frodo';

n  UPDATE users SET top_places = top_places + [ 'mordor' ] WHEREuser_id = 'frodo';

n  UPDATE users SET top_places[2] = 'riddermark' WHERE user_id ='frodo';

n  DELETE top_places[3] FROM users WHERE user_id = 'frodo';

n  UPDATE users SET top_places = top_places - ['rivendell'] WHEREuser_id = 'frodo';

²  map類型

n  ALTER TABLE users ADD todo map<timestamp, text>;

n  UPDATE users SET todo =

  { '2012-9-24' : 'entermordor',

  '2012-10-2 12:00' : 'throwring into mount doom' }

WHERE user_id = 'frodo';

n  UPDATE users SET todo['2012-10-2 12:00'] = 'throw my precious intomount doom'WHERE user_id = 'frodo';

n  INSERT INTO users (user_id,todo)  VALUES ('miaohan', { '2013-9-22 12:01' : 'birthday wishes to Bilbo',  '2013-10-1 18:00' : 'Check into Inn of Prancing Pony' });

n  DELETE todo['2012-9-24'] FROM users WHERE user_id = 'frodo';

n  UPDATE users USING TTL 60 SET todo['2012-10-1'] = 'find water' WHEREuser_id = 'frodo';

注;可爲上述三種集合類型的每個元素設置單獨的過期時間。

 創建和使用索引

CREATE INDEXlast_name_key ON users(last_name);

SELECT * FROMusers WHERE last_name = 'Baggins'(需創建了索引才能在WHERE中使用該列進行查詢,暫無多列索引,需逐列分別建立索引)

 輕量級事務

使用IF從句實現

n  INSERT INTO emp(empid,deptid,address,first_name,last_name) VALUES(102,14,'luoyang','Jane Doe','li') IF NOT EXISTS;

n  UPDATE emp SET address = 'luoyang' WHERE empid = 103 and deptid = 16IF last_name='zhang';

 使用counter

用於記錄特定時間或處理的次數。對應的column需使用counter數據類型,該類數據一般存儲於專門的表中,且使用UPDATE載入並增減counter值,不使用INSERT插入counter值。只能在原數值的基礎上增減,不能爲直接指定一個數值。

 CREATEKEYSPACE counterks WITH REPLICATION = { 'class' : 'SimpleStrategy','replication_factor' : 3 };

CREATE TABLEcounterks.page_view_counts

  (counter_valuecounter,

  url_name varchar,

  page_name varchar,

  PRIMARY KEY (url_name, page_name)

);

UPDATEcounterks.page_view_counts

 SET counter_value = counter_value + 1

 WHERE url_name='www.datastax.com' ANDpage_name='home';

若原來不存在WHERE條件中指定的內容,該條語句會將表中的url_name值置爲'www.datastax.com'將page_name置爲’home’,將counter_value指定爲默認初始值0加1。若WHERE條件中指定的內容存在,則將counter_value置爲原來的counter_value加1

UPDATEcounterks.page_view_counts

 SET counter_value = counter_value + 2

 WHERE url_name='www.baidu.com' ANDpage_name='map';

 更多CQL內容請參見:http://www.datastax.com/documentation/cql/3.1/webhelp/index.html

6安全

三方面安全策略

Ø  Client-to-node/node-to-node加密(SSL):加密傳輸的數據

Ø  基於登錄賬戶/密碼的認證:確定誰可以使用數據庫

Ø  對象授權管理:確定用戶可在在數據庫上幹什麼

6.1 SSL加密

6.1.1Client-to-node

準備證書

Ø  爲每個節點產生私鑰/公鑰對

keytool-genkey -alias cassandra_vms00780 -keystore ~/keys/.keystore

 Ø  導出公鑰部分到單獨的證書文件,並拷貝該文件到其他所有節點

keytool-export -alias cassandra_vms00780 -file ~keys/cassandra_vms00780.cer -keystore ~/keys/.keystore

 Ø  將每個節點的證書添加到所有節點的信任庫中

keytool-import -v -trustcacerts -alias cassandra_vms00780 -file cassandra_vms00780.cer–keystore  ~/keys/ .truststore

 Ø  保證將.keystore和truststore文件分發到所有節點

Ø  確認.keystore文件只對Cassandradaemon可讀

 編輯配置文件

配置cassandra.yaml文件中client_encryption_options部分的參數

client_encryption_options:

enabled: true

keystore: ~keys/.keystore## .keystore file路徑

keystore_password:<keystore password> ## 產生keystore時用的密碼

truststore: ~keys/.truststore

truststore_password:<truststore password>

require_client_auth:<true or false>

6.1.2node-to-node

準備證書

同上

 編輯配置文件

配置cassandra.yaml文件中server_encryption_options部分的參數

server_encryption_options:

   internode_encryption: <internode_option:all/none/dc/rack>

   keystore: ~keys/.keystore

   keystore_password: <keystore password>

   truststore:~keys/.truststore

   truststore_password: <truststorepassword>

   require_client_auth: <true or false>

6.1.3在cqlsh中使用SSL

可在主目錄依據樣例文件cqlshrc.sample創建.cqlshrc文件

[authentication]

username = cassandra

password = cassandra

 [connection]

hostname = localhost

port = 9160

factory =cqlshlib.ssl.ssl_transport_factory

 [ssl]

certfile =~/keys/cassandra.cert

validate = true

 [certfiles] 

192.168.1.3 =~/keys/cassandra01.cert

192.168.1.4 =~/keys/cassandra02.cert

6.2內部認證

基於Cassandra控制的登錄賬戶和密碼

認證用的登錄名和經bcrypt散列的密碼存儲於system_auth.credentials表中

6.2.1配置

第一步

Ø  若要使用基於用戶名/密碼的認證機制,需要先配置cassandra.yaml文件中authenticator的值爲PasswordAuthenticator(該參數默認值爲AllowAllAuthenticator,即,不進行任何認證)。這樣cassandra會在system_auth.user創建一個超級用戶,用戶名和密碼均爲cassandra。之後,配置system_auth這個keyspace的replication factor爲較大的值(詳見第5章使用創建、更新keyspace部分的內容)

認證語句

Ø  ALTER USER

ALTER USERuser_name WITH PASSWORD 'password'  (NOSUPERUSER| SUPERUSER) 

注:SUPERUSER可更改其他用戶的密碼和SUPERUSER狀態(NOSUPERUSER或 SUPERUSER),但不能改變自己的SUPERUSER狀態。普通用戶只能更改自己的密碼。

Ø  CREATE USER

CREATE USERuser_name WITH PASSWORD 'password'  (NOSUPERUSER| SUPERUSER)

只有SUPERUSER可創建用戶,創建的用戶默認爲NOSUPERUSER

Ø  DROP USER

DROP USER user_name

只有SUPERUSER可刪除用戶,用戶不能自己刪除自己。

Ø  LIST USERS

LIST USERS(爲什麼沒有結果???)

列出用戶

更改默認SUPERUSER

Ø  使用默認SUPERUSER也即cassandra登錄

./cqlsh -ucassandra -p Cassandra

 Ø  新建另一SUPERUSER,之後刪除原cassandraSUPERUSER

create userus_yanzhaozhang with password 'cassandra' superuser;

drop usercassandra;

 Ø  重啓cassandra,使用新的SUPERUSER登錄,執行後續操作。

6.2.2使用cqlsh登錄

若使用cqlsh登錄,可將認證信息存儲於.cqlshrc文本文件,放置在用戶主目錄中,以免重複錄入登錄信息。注意對該文本文件設置對應的權限以防信息泄露。

[authentication]

username = example_username

password = example_password

6.3內部授權

對象權限管理基於內部授權,與關係型數據庫GRANT/REVOKE語法類似。

首先要配置cassandra.yaml中authorizer的值爲CassandraAuthorizer(默認爲AllowAllAuthorizer,允許任何用戶的任何動作),設定爲該值後會將授權信息存儲在system_auth.permissions表中。

之後,配置system_auth這個keyspace的replicationfactor爲較大的值。

通過設置permissions_validity_in_ms選項調整權限有效期。

 語法

GRANTpermission_name PERMISSION

| ( GRANT ALLPERMISSIONS ) ON resource TO user_name


REVOKE (permission_name PERMISSION )

| ( REVOKE ALLPERMISSIONS )

ON resourceFROM user_name

 

LISTpermission_name PERMISSION

| ( LIST ALLPERMISSIONS )

    ON resource OF user_name

    NORECURSIVE

 

其中permission_name爲

Ø  ALL

Ø  ALTER

Ø  AUTHORIZE

Ø  CREATE

Ø  DROP

Ø  MODIFY

Ø  SELECT

resource爲

Ø  ALL KEYSPACES

Ø  KEYSPACE keyspace_name

Ø  TABLE keyspace_name.table_name

6.4配置防火牆端口訪問

需在防火牆策略中開放一下端口

Ø  公共端口

n  22 ssh端口

n  8888 OpsCenter website端口

Ø  Cassandra節點間端口

n  1024+ JMX reconnection/loopback端口

n  7000 Cassand集羣內節點間通訊端口

n  7199 Cassandra JMX 監控端口

n  9160 Cassandra客戶端端口

Ø  Cassandra OpsCenter 端口

n  61620 OpsCenter監控端口

n  61621 OpsCenter代理端口

7架構

7.1梗概

點對點分佈式系統,集羣中各節點平等,數據分佈於集羣中各節點,各節點間每秒交換一次信息。每個節點的commit log捕獲寫操作來確保數據持久性。數據先被寫入memtable-內存中的數據結構,待該結構滿後數據被寫入SSTable-硬盤中的數據文件。所有的寫內容被自動在集羣中分區並複製。

Cassandra數據庫面向行。授權用戶可連接至任意數據中心的任意節點,並通過類似SQL的CQL查詢數據。集羣中,一個應用一般包含一個keyspace,一個keyspace中包含多個表。

客戶端連接到某一節點發起讀或寫請求時,該節點充當客戶端應用與擁有相應數據的節點間的協調者(coordinator)以根據集羣配置確定環中的哪個節點當獲取這個請求。

 關鍵詞

Ø  Gossip:點對點通信協議,用以Cassandra集羣中節點間交換位置和狀態信息。

Ø  Partitioner:決定如何在集羣中的節點間分發數據,也即在哪個節點放置數據的第一個replica。

Ø  Replica placement strategy:決定在哪些節點放置數據的其他replica。Cassandra在集羣中的多個節點存儲數據的多份拷貝-replicas來確保可靠和容錯。

Ø  Snitch:定義了複製策略用來放置replicas和路由請求所使用的拓撲信息

Ø  cassandra.yaml文件:Cassandra主配置文件

Ø  system:Cassandra的系統keyspace,存放table、keyspace的屬性信息等。而屬性信息可通過CQL或其他驅動設置。

7.2節點間通信

Cassandra使用點對點通訊協議gossip在集羣中的節點間交換位置和狀態信息。gossip進程每秒運行一次,與至多3個其他節點交換信息,這樣所有節點可很快了解集羣中的其他節點信息。

 配置gossip(在cassandra.ymal中設置)

Ø  cluster_name:節點所屬集羣名,集羣中每個節點應相同。

Ø  listen_address:供其他節點連接至該節點的IP地址或主機名,當由localhost設爲公共地址。

Ø  seed_provider:逗號分隔的IP地址(種子列表),gossip通過種子節點學習環的拓撲,集羣中各節點種子列表當相同。多數據中心集羣中每個數據中心的種子列表當至少包含一個該中心內的節點。

Ø  storage_port:節點間通訊端口,集羣中各節點當一致。

Ø  initial_token:用於single-node-per-token結構,節點在環空間只擁有一段連續的token範圍。

Ø  num_tokens:用於virtual nodes,定義了節點在環空間所擁有的隨機分配的token數目。

 失敗檢測與恢復

Ø  gossip可檢測其他節點是否正常以避免將請求路由至不可達或者性能差的節點(後者需配置爲dynamic snitch方可)。

Ø  可通過配置phi_convict_threshold來調整失敗檢測的敏感度。

Ø  對於失敗的節點,其他節點會通過gossip定期與之聯繫以查看是否恢復而非簡單將之移除。若需強制添加或移除集羣中節點需使用nodetool工具。

Ø  一旦某節點被標記爲失敗,其錯過的寫操作會有其他replicas存儲一段時間(需開啓hinted handoff,若節點失敗的時間超過了max_hint_window_in_ms,錯過的寫不再被存儲。)Down掉的節點經過一段時間恢復後需執行repair操作,一般在所有節點運行nodetool repair以確保數據一致。

7.3數據複製和分發

Cassandra中分發、複製同時進行。Cassandra被設計爲點對點系統,會創建數據的多個副本存儲在集羣中的一組節點中。Cassandra中數據被組織爲表,由primary key標識,primary key決定數據將被存儲在哪個節點。

 需指定的內容

Virtual nodes:指定數據與物理節點的所屬關係

Partitioner:在集羣內劃分數據

Replicationstrategy:決定如何處理每行數據的replicas

Snitch:定義replicationstrategy放置數據的replicas時使用的拓撲信息

 一致性哈希

表中每行數據由primary key標識,Cassandra爲每個primarykey分配一個hash值,集羣中每個節點擁有一個或多個hash值區間。這樣便可根據primary key對應的hash值將該條數據放在包含該hash值的hash值區間對應的節點中。

 虛擬節點

使用虛擬接電視數據在集羣中的分佈

若不使用虛擬節點則需手工爲集羣中每個節點計算和分配一個token。每個token決定了節點在環中的位置以及節點應當承擔的一段連續的數據hash值的範圍。如上圖上半部分,每個節點分配了一個單獨的token代表環中的一個位置,每個節點存儲將row key映射爲hash值之後落在該節點應當承擔的唯一的一段連續的hash值範圍內的數據。每個節點也包含來自其他節點的row的副本。而是用虛擬節點允許每個節點擁有多個較小的不連續的hash值範圍。如上圖中下半部分,集羣中的節點是用了虛擬節點,虛擬節點隨機選擇且不連續。數據的存放位置也由row key映射而得的hash值確定,但是是落在更小的分區範圍內。

 使用虛擬節點的好處

Ø  無需爲每個節點計算、分配token

Ø  添加移除節點後無需重新平衡集羣負載

Ø  重建死掉的節點更快

Ø  改善了在同一集羣使用異種機器

 數據複製

Cassandra在多個節點中存放replicas以保證可靠性和容錯性。replicationstrategy決定放置replicas的節點。replicas的總數由複製因子- replication factor確定,比如因子爲2代表每行有兩份拷貝,每份拷貝存儲在不同的節點中。所有的replicas無主從之分。replication factor通常不能超過集羣中節點總數。然而,可現增加replication facto之後在將節點增至期望的數量。當replication facto超過總結點數時,寫操作被拒絕,但讀操作可進行,只要滿足期望的一致性級別。

 當前有兩種可用的複製策略:

Ø  SimpleStrategy:僅用於單數據中心,將第一個replica放在由partitioner確定的節點中,其餘的replicas放在上述節點順時針方向的後續節點中。

Ø  NetworkTopologyStrategy:可用於較複雜的多數據中心。可以指定在每個數據中心分別存儲多少份replicas。在每個數據中心放置replicas的方式類似於SimpleStrategy,但傾向於將replicas放在不同rack,因爲同一rack的節點傾向於同時失敗。配置每個數據中心分別放置多少replicas時要考慮兩個主要方面:(1)可滿足本地讀而非跨數據中心讀;(2)失敗場景。兩種常用的配置方式爲(1)每個數據中心兩份replicas,(2)每個數據中心3份replicas。當然,用於特殊目的的非對稱配置也是可以的,比如在讀操作較頻繁的數據中心配置3份replicas而在用於分析的數據中心配置一份replicas。

複製策略在創建keyspace時指定,如

CREATEKEYSPACE Excelsior WITH REPLICATION = { 'class' : 'SimpleStrategy','replication_factor' : 3 };

CREATEKEYSPACE "Excalibur" WITH REPLICATION = {'class' :'NetworkTopologyStrategy', 'dc1' : 3, 'dc2' : 2};

其中dc1、dc2這些數據中心名稱要與snitch中配置的名稱一致。

7.4Partitioners

在Cassandra中,table的每行由唯一的primarykey標識,partitioner實際上爲一hash函數用以計算primary key的token。Cassandra依據這個token值在集羣中放置對應的行。

 三種partitioner(在cassandra.yaml中設置)

Ø  Murmur3Partitioner:當前的默認值,依據MurmurHash哈希值在集羣中均勻分佈數據。

Ø  RandomPartitioner:依據MD5哈希值在集羣中均勻分佈數據。

Ø  ByteOrderedPartitioner:依據行key的字節從字面上在集羣中順序分佈數據。(不推薦使用)

Murmur3Partitioner和RandomPartitioner使用token向每個節點指派等量的數據從而將keyspace中的表均勻分佈在環中,即使不同的表使用不同的primary key。讀寫請求均被均勻的分佈。ByteOrderedPartitioner允許通過primary key順序掃描(可通過index達到同樣目的),但已引起如下問題(1)較複雜的負載均衡,(2)順序的寫易導致熱點,(3)多表不均勻的負載均衡。

 注意:若使用虛擬節點(vnodes)則無需手工計算tokens。若不使用虛擬節點則必須手工計算tokens將所得的值指派給cassandra.ymal主配置文件中的initial_token參數。具體可參考:http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/architecture/../configuration/configGenTokens_c.html

7.5Snitches

提供網絡拓撲信息,用以確定向/從哪個數據中心或者網架寫入/讀取數據。

注意:(1)所有節點需用相同的snitch;(2)集羣中已插入數據後由更改了snitch則需運行一次fullrepair。

Ø  Dynamic snitching

監控從不同replica讀操作的性能,選擇性能最好的replica。dynamic snitch默認開啓,所有其他snitch會默認使用dynamic snitch 層。

Ø  SimpleSnitch

默認值,用於單數據中心部署,不使用數據中心和網架信息。使用該值時keyspace複製策略中唯一需指定的是replication factor

Ø  RackInferringSnitch

根據數據中心和網架確定節點位置,而數據中心及網架信息又有節點的IP地址隱含指示。

Ø  PropertyFileSnitch

根據數據中心和網架確定節點位置,而網絡拓撲信息又由用戶定義的配置文件cassandra-topology.properties 獲取。在節點IP地址格式不統一無法隱含指示數據中心及網架信息或者複雜的複製組中使用該值。需注意的是:(1)配置文件中數據中心名需與keyspace中複製策略中指定的數據中心名稱一致;(2)配置文件中需包含集羣中任一節點;(3)集羣中各節點內cassandra-topology.properties配置文件需相同。

Ø  GossipingPropertyFileSnitch

Ø  在cassandra-rackdc.properties配置文件中定義本節點所屬的數據中心和網架,利用gossip協議與其他節點交換該信息。若從PropertyFileSnitch切至該值,則需逐節點逐次更新值爲GossipingPropertyFileSnitch以確保gossip有時間傳播信息。

Ø  EC2Snitch

用於部署在Amazon EC2中且所有節點在單個區域中的集羣。

Ø  EC2MultiRegionSnitch

Ø  用於部署在AmazonEC2中,且節點跨多個區域的集羣。

7.6客戶端請求

client連接至節點併發出read/write請求時,該node充當client端應用與包含請求數據的節點(或replica)之間的協調者,它利用配置的partitioner和replicaplacement策略確定那個節點當獲取請求。

7.6.1寫請求

協調者(coordinator)將write請求發送到擁有對應row的所有replica節點,只要節點可用便獲取並執行寫請求。寫一致性級別(write consistency level)確定要有多少個replica節點必須返回成功的確認信息。成功意味着數據被正確寫入了commit log個memtable。

 上例爲單數據中心,11個節點,複製因子爲3,寫一致性等級爲ONE的寫情況。

7.6.2多數據中心的寫請求

基本同上,但會在各數據中心分別選擇一個協調者以處理該數據中心內的寫請求。與client直接連接的coordinator節點只需將寫請求發送到遠程數據中心的coordinator一個節點即可,剩餘的由該coordinator完成。若一致性級別設置爲ONE或者LOCAL_QUORUM則僅與直接協調者位於同一數據中心的節點需返回成功確認。

 上例爲雙單數據中心,各11個節點,複製因子爲6,寫一致性等級爲ONE的寫情況。

7.6.3讀請求

Ø  直接讀請求

Ø  後臺讀修復請求

 與直接讀請求聯繫的replica數目由一致性級別確定。後臺讀修復請求被髮送到沒有收到直接讀請求的額外的replica,以確保請求的row在所有replica上一致。

 協調者首先與一致性級別確定的所有replica聯繫,被聯繫的節點返回請求的數據,若多個節點被聯繫,則來自各replica的row會在內存中作比較,若不一致,則協調者使用含最新數據的replica向client返回結果。

 同時,協調者在後臺聯系和比較來自其餘擁有對應row的replica的數據,若不一致,會向過時的replica發寫請求用最新的數據進行更新。這一過程叫read repair。

 上例爲單數據中心,11個節點,複製因子爲3,一致性級別爲QUORUM的讀情況。

8數據庫內部

8.1數據管理

使用類似Log-StructuredMerge Tree的存儲結構,而非典型的關係型數據庫使用的B-Tree結構。存儲引擎連續的將數據以追加的模式寫物磁盤並持續存儲數據。節點間/內的操作並行運行。因不使用B-Tree故無需協同控制,在寫時不必執行更新。Cassandra在SSD中性能表現極佳。

 高吞吐量和低延遲

操作並行運行,吞吐量和延遲相互獨立。log-structured設計避免詢盤開銷。去除on-disk數據修改,省時且延長SSD壽命。無on-disk型的數據修改故無需鎖定寫請求這樣的協同控制。無主、從,在所有節點運行同樣的代碼。

 單獨的表目錄

/var/lib/cassandra/data/ks1/cf1/ks1-cf1-ja-1-Data.db

其中/var/lib/cassandra/data/爲cassandra.yaml中指定的數據文件目錄。ks1爲keyspace名cf1/爲columnfamilies名。這樣可將表連接至選定的目標位置以便於將活躍的表移到更快的存儲介質,或者將表分不到多個可用的存儲設備以均衡負載

8.2關於寫

複製的角色

通過在多個同級節點創建數據的多個副本保證可靠性和容錯。表是非關係型的,無需過多額外工作來維護關聯的表的完整性,因此寫操作較關係型數據庫快很多。

 寫過程

先將數據寫進內存中的數據結構memtable,同時追加到磁盤中的commitlog中。表使用的越多,對應的memtable應越大,cassandra動態的爲memtable分配內存,也可自己手工指定。memtable內容超出指定容量後memtable數據(包括索引)被放進將被刷入磁盤的隊列,可通過memtable_flush_queue_size配置隊列長度。若將被刷入磁盤的數據超出了隊列長度,cassandra會鎖定寫。memtable表中的數據由連續的I/O刷進磁盤中的SSTable,之後commit log被清空。每個表有獨立的memtable和SSTable。

8.3關於更新、刪除和hinted handoff writes

更新(cassandra中插入重複的primarykey也被看做是更新操作)

不直接在磁盤中原地更新而是先在memtable進行所有的更新。最後更新內容被刷入磁盤存儲在新的SSTable中,僅當column的時間戳比既存的column更新時才覆蓋原來的數據。

 刪除

Ø  不會立即從磁盤移除刪除的數據

被刪除的數據會被tombstone標記以指定其狀態,它會存在一定的時間(由gc_grace_seconds指定),超出該時間後compaction進程永久刪除該column。

Ø  若不例行性的執行節點repair操作,被刪除的column可能重新出現

若刪除期間節點down掉,被標記爲tombstone的column會發送信號給Cassandra使其重發刪除請求給該replica節點。若replica在gc_grace_seconds期間復活,會最終受到刪除請求,若replica在gc_grace_seconds之後復活,節點可能錯過刪除請求,而在節點恢復後立即刪除數據。需定期執行節點修復操作來避免刪除數據重現。

 hinted handoff writes

在不要求一致性時確保寫的高可用,在cassandra.yaml中開啓該功能。執行write操作時若擁有對應row的replica down掉了或者無迴應,則協調者會在本地的system.hints表中存儲一個hint,指示該寫操作需在不可用的replica恢復後重新執行。默認hints保存3小時,可通過max_hint_window_in_ms改變該值。

 提示的write不計入consistencylevel中的ONE,QUORUM或ALL,但計入ANY。ANY一致性級別可確保cassandra在所有replica不可用時仍可接受write,並且在適當的replica可用且收到hint重放後該write操作可讀。

 移除節點後節點對應的hints自動移除,刪除表後對應的hints也會被移除。

 仍需定期執行repair(避免硬件故障造成的數據丟失)

8.4關於讀

從SSD並行隨機讀取,延時極低(不推薦cassandra使用轉盤式硬盤)。以partition key讀/寫,消除了關係型數據庫中複雜的查詢。

 讀SSTable

首先檢查Bloom filter,每個SSTable都有一個Bloomfilter,用以在進行任何磁盤I/O前檢查請求的partition key對應的數據在SSTable中存在的可能性。若數據很可能存在,則檢查Partition key cache(Cassandra表partition index的緩存),之後根據index條目是否在cache中找到而執行不同步驟:

Ø  找到

從compression offset map中查找擁有對應數據的壓縮快。

從磁盤取出壓縮的數據,返回結果集。

Ø  未找到

搜索Partition summary(partition index的樣本集)確定index條目在磁盤中的近似位置。

從磁盤中SSTable內取出index條目。

從compression offset map中查找擁有對應數據的壓縮快。

從磁盤取出壓縮的數據,返回結果集。

 回顧插入/更新數據


讀的過程

由insert/update過程可知,read請求到達某一節點後,必須結合所有包含請求的row中的column的SSTable以及memtable來產生請求的數據。

                                                                                                

例如,要更新包含用戶數據的某個row中的email 列,cassandra並不重寫整個row到新的數據文件,而僅僅將新的email寫進新的數據文件,username等仍處於舊的數據文件中。上圖中紅線表示Cassandra需要整合的row的片段用以產生用戶請求的結果。爲節省CPU和磁盤I/O,Cassandra會緩存合併後的結果,且可直接在該cache中更新row而不用重新合併。

8.5關於事務和協同控制

不支持RDBMS中具有回滾和鎖定機制的ACID事務,但提供了一定程度的原子性(行級)、隔離性(行級)、持久性和eventual/tunable 類型的一致性(因不支持連接和外鍵,故不提供ACID場景下的一致性)。

 Ø  原子性

row-level,對一個row的插入/更新被當做一個原子操作。不支持要麼都做要麼都不做的多行插入/更新。不支持在一個replica上write成功而在其他replica上write失敗的回滾。用時間戳確定column的最新更新。若多個session同時更新同樣的column則使用最近的更新。

Ø  一致性

l  Tuneable一致性

提供partition容錯。用戶可以以單個操作爲基礎決定需多少個節點接收DML操作或響應SELECT操作。

l  Linearizable一致性

l  輕量事務(compare-and-set)的一系列隔離級別。在tuneable一致性不足以滿足要求時使用,如執行無間斷的相繼操作或同時/不同時運行一個操作產生同樣的結果。Cassandra2.0使用類似2-phase commit的Paxos consensus協議實現Linearizable一致性。(爲支持該一致性引入了SERIAL類型的consistency level及在CQL中使用了帶IF從句的輕量事務)

Ø  隔離性

Cassandra2.0開始支持row-level的隔離性。對行的寫操作在完成之前對其他用戶不可見。

Ø  持久性

同時將數據寫入內存中的memtable及磁盤中的commit log。服務器故障時若memtable尚未刷入磁盤,在故障恢復後可重放commit log恢復丟失數據。這提供了本地持久性。數據在其他節點的副本加強了持久性。

 輕量事務

Cassandra2.0中引入,彌補Tuneable一致性。

n  INSERT INTO emp(empid,deptid,address,first_name,last_name) VALUES(102,14,'luoyang','Jane Doe','li') IF NOT EXISTS;

n  UPDATE emp SET address = 'luoyang' WHERE empid = 103 and deptid = 16IF last_name='zhang';

8.6配置數據一致性

Cassandra中,一致性級別可配置,以確定請求的數據如何在不同的replica保持一致性,從而平衡響應時間和數據精確性。

 Ø  寫一致性

指明在返回確認至客戶端前,write操作必須成功的replica數。

l  ANY:write至少在一個replica成功。即使所有replica 都down掉,在寫hinted handoff後write仍成功。在replica恢復後該write可讀。

l  ONE:write必須成功寫入至少一個replica的commit log和memtable。

l  TWO:至少兩個

l  THREE:至少三個

l  QUORUM:至少(replication_factor/ 2) + 1個

l  LOCAL_QUORUM:至少(replication_factor/ 2) + 1個,且與協調者處於同一數據中心

l  EACH_QUORUM:所有數據中心,至少(replication_factor/ 2) + 1個

l  ALL:全部

l  SERIAL:至少(replication_factor/ 2) + 1個,用於達成輕量事務的linearizable consistency

需注意的是:實際上write還是會被髮到所有相關的replica中,一致性級別只是確定必需要反饋的replica數。

 Ø  讀一致性

指明在返回數據值客戶端前,需要相應read請求的相關replica數。Cassandra從這些數量的replica中根據時間戳檢查最新的數據。級別同寫一致性。

 可通過cqlsh命令CONSISTENCY設置keyspace的一致性,也可編程設置一致性。

9操作

9.1監控Cassandra集羣

工具:nodetool utility、DataStaxOpsCenter、JConsole

 Ø  nodetool utility:Cassandra發行版附帶的命令行工具,用於監控和常規數據庫操作。一些常用命令如status、cfstats、cfhistograms、netstats、tpstats等。

Ø  DataStax OpsCenter:圖形用戶界面工具,從中央控制檯監控和管理集羣中所有節點。

Ø  JConsole:JMX兼容工具用以監控java應用程序,提供Overview、Memory、Thread、Classes、VM summary、Mbeans方面的信息。

9.2調整Bloom filters

Bloom filters用以在執行I/O前確定SSTable是否含特定的row。用於index掃描而不用於range掃描。通過bloom_filter_fp_chance參數配置其屬性值,範圍爲0至1.0(關閉),值越大則使用的內存越少,但也意味着若SSTable由較多碎片則導致較高的磁盤I/O。默認值依賴於compaction_strategy類型。值的設置依賴工作負荷,如,若需在一特定表上運行繁重的scan則需將bloom_filter_fp_chance設置高一點。

 通過如下語句設置:

ALTER TABLEaddamsFamily WITH bloom_filter_fp_chance = 0.1;

設置好後需使用Initiatecompaction或Upgrade SSTables方式之一重新產生Bloom filter。

9.3數據緩存

兩類cache:partitionkey cache和row cache

Ø  partition key cache:Cassandra表partition index的cache

Ø  row cache:一個row首次被訪問後整個row(合併自多個對應的SSTable及memtable)被放在row cache中以便於後續對改row的訪問能直接由內存獲取數據。

 對於很少訪問的archive表當禁用緩存。

 開啓與配置cache

Ø  開啓

CREATE TABLEusers (

  userid text PRIMARY KEY,

  first_name text,

  last_name text,

)

WITH caching ='all';

Ø  配置

在cassandra.yaml中,調整下列參數;

l  key_cache_keys_to_save

l  key_cache_save_period

l  key_cache_size_in_mb

l  row_cache_keys_to_save

l  row_cache_size_in_mb

l  row_cache_save_period

l  row_cache_provider

工作原理:

第一個read操作直接命中rowcache,從內存取出數據。第二個read操作爲命中row cache,但命中partition key cache,並由此整合所有相關的SSTable及memtable中的片段爲請求的row,返回row並寫進row cache。

 cache使用優化建議

Ø  將很少請求的數據或row很長的數據放在cache較小或不使用cache的表中

Ø  用較多的節點部署各節點負載較輕的集羣

Ø  邏輯上將read稠密的數據分開在離散的表中

9.4配置memtable吞吐量

可改善write性能。Cassandra在commit logspace threshold超出時將memtables內容刷進磁盤創建SSTable。在cassandra.ymal中配置commit log space threshold來調整memtable吞吐量。配置的值依賴於數據和write負載。下列兩種情況可考慮增加吞吐量:

Ø  write負載包含大量在小數據集上的更新操作

Ø  穩定持續的寫操作

9.5Compaction與Compression

9.5.1Compaction

週期性的後臺進程。Compaction期間Cassandra通過整合row片段合併SSTable、移除過期的tombstones、重建索引等,並在新SSTable合併完成後移除舊的SSTable。

 兩類Compaction

Ø  SizeTieredCompactionStrategy

收集尺寸相近的SSTable合併爲一個較大的SSTable。

Ø  LeveledCompactionStrategy

創建相對較小的SSTable,尺寸被固定爲不同等級(L0、L1、L2……),同一級內SSTable大小相同,每差一個等級尺寸差10倍。SSTable從較小的等級逐漸合併至較高的等級。

 Compaction操作會臨時增加磁盤I/O,但完成後可改善read性能。

 開啓與配置Compaction

Ø  使用CQL語句CREATE/ALTER TABLE

l  ALTER TABLE users WITH

 compaction = { 'class' : 'LeveledCompactionStrategy', 'sstable_size_in_mb' : 10  }

l  ALTER TABLE users

 WITH compaction ={'class' : 'SizeTieredCompactionStrategy','min_threshold' : 6 }

更多屬性參見CQL keyspace and table properties.

 Ø  配置cassandra.yaml文件

l  snapshot_before_compaction

l  in_memory_compaction_limit_in_mb

l  multithreaded_compaction

l  compaction_preheat_key_cache

l  concurrent_compactors

l  compaction_throughput_mb_per_sec

9.5.2Compression

通過減少數據體積和磁盤I/O來最大化存儲能力。大大提升讀性能且不會像傳統關係型數據庫中的Compression操作降低write性能。

 什麼時候執行Compression

適用於擁有大量的row且每個row與其他row有一樣的column或儘可能多相同的column的表。越相似壓縮比越高,性能提升越明顯。row具有差異較大的column集的表不適於Compression。如Dynamic表。

 配置好compression後後續創建的SSTable被壓縮,之前已經存在的SSTable不被立即壓縮直到正常的Cassandracompaction進程開始。可使用nodetool upgradesstables命令強制壓縮既存的SSTable

 配置Compression

Ø  禁用

CREATE TABLEDogTypes (

              block_id uuid,

              species text,

              alias text,

              population varint,

              PRIMARY KEY (block_id)

            )

            WITH compression = {'sstable_compression' : '' };

Ø  開啓

CREATE TABLEDogTypes (

              block_id uuid,

              species text,

              alias text,

              population varint,

              PRIMARY KEY (block_id)

            )

            WITH compression = {'sstable_compression' : 'LZ4Compressor' };

Ø  調整

ALTER TABLECatTypes

  WITH compression = { 'sstable_compression' :'DeflateCompressor', 'chunk_length_kb' : 64 }

9.6調整Java資源

性能下降或內存消耗過多時需考慮調整Java資源。有兩個文件用於Cassandra中環境設置:

Ø  comf/cassandra-env.sh:配置JVM

Ø  bin、cassandra-in.sh:配置Cassandra環境變量

 調整Heap尺寸時MAX_HEAP_SIZE與HEAP_NEWSIZE要同時設置,前者設置JVM最大heap尺寸,後者設置新生代的尺寸,新生代尺寸越大垃圾回收暫停時間越長,反之垃圾回收消耗越大。

 當前默認配置:

系統內存

Heap 大小

少於 2GB

系統內存的1/2 

2GB t到 4GB

1GB

大於 4GB

系統內存的1/4,但不會超過8GB

heap大小並非越大越好:首先Java6處理8GB以上的垃圾收集的能力會迅速縮減;其次會減少操作系統緩存頁所能使用的內存。

 Cassandra1.2以後版本Bloomfilter和compression offset map是off-heap的,不算在JVM的heap之內。Cassandra2.0後partition summary也是off-heap的。若在Cassandra中使用JNA庫,row cache也會升級爲off-heap。這些可幫減少heap大小,增強JVM GC性能,從而增加Cassandra高效處理每個節點中數據的能力。

 若GC頻發發生且在適度的時間完成表明JVM GC壓力過大,此時需作出增加節點、降低cache大小、調整JVM中有關GC的參數等補救措施。

 JavaManagement Extensions (JMX)提供了管理和監控Java應用和服務的各種工具。如JConsole,、the nodetool utility和 DataStax OpsCenter這些JMX兼容工具。

 comf/cassandra-env.sh中其他相關參數

Ø  com.sun.management.jmxremote.port

Ø  com.sun.management.jmxremote.ssl

Ø  com.sun.management.jmxremote.authenticate

Ø  -Djava.rmi.server.hostname

9.7修復 node

使用nodetool的repair命令,修復與給定的數據範圍相關的replica間的不一致性。在下屬情形運行修復:

Ø  規律的、計劃的集羣維護操作期間(除非沒有執行過delete)

Ø  節點恢復後

Ø  在包含較少被訪問的數據的節點上

Ø  在down掉的節點更新數據

 運行節點修復的方針:

Ø  常規修復操作執行次數由gc_grace值硬性規定。需在該時間內在每個節點至少運行一次修復操作。

Ø  同時在多於一個的節點運行常規修復時需謹慎,最好在低峯期規律運行修復。

Ø  在很少delete或overwrite數據的系統中,可增加gc_grace的值。

 修復操作消耗磁盤I/O,可通過下述途徑減輕:

Ø  使用nodetool的compactionthrottling選項。

Ø  使用nodetoolsnapshot之後從snapshot執行修復。

 修復操作會導致overstreaming(問題源於Cassandra內部Merkletrees數據結構)。比如只有一個損壞的partition但卻需發送很多的stream,且若節點中存在的partition越多問題越嚴重。這會引起磁盤空間浪費和不必要的compaction。可使用subrange 修復來減輕overstreaming。subrange repair只修復屬於節點的部分數據。

9.8添加/移除節點或數據中心

Ø  在既存集羣中添加節點

以使用vnodes的節點爲例(推薦此種方式,虛擬節點相關內容見第7節)

1.        在新節點安裝Cassandra,關閉cassandra,清除數據。

2.        在cassandra.yaml和cassandra-topology.properties中配置如下屬性:

l  cluster_name

l  listern_address/broadcast_address

l  endpoint_snitch

l  num_tokens

l  seed_provider

3.        逐個啓動新節點中的cassandra,不同節點的初始化之間保持兩分鐘的間隔。可用nodetool netstats監控啓動和數據流處理

4.        待所有新節點運行起來後逐個在每個之前已存在的節點執行nodetool cleanup來移除不再屬於這些節點的key。在下一個節點執行nodetool cleanup前必須等上一個節點中的nodetool cleanup結束。另外cleanup操作可考慮在低峯期進行。

 Ø  向既存集羣中添加數據中心

以使用vnodes的節點構成的集羣爲例

1.        確保keyspace使用NetworkTopologyStrategy複製策略

2.        對於每個新節點在cassandra.yaml中設置如下屬性

l  auto_bootstrap: false.

l  設置其他與所屬集羣匹配的屬性(參見上一部分:在既存集羣中添加節點)

3.        根據設置的snitch類型在各新節點配置對應的指明網絡拓撲的配置文件(無需重啓)

4.        確保使用的客戶端不會自動探測新的節點。

5.        若使用QUORUM一致性級別,需檢查LOCAL_QUORUM或EACH_QUORUM一致性級別是否滿足多數據中心的要求

6.        逐個在每個節點開啓cassandra。注意初始化時間間隔。

7.        所有節點運行起來後執行下列操作

 Ø  替換死掉的節點

以使用vnodes的節點構成的集羣爲例

1.        用nodetool status命令確認環中死掉的節點,從輸出中記錄該節點的HOST ID。

2.        添加並啓動新的替代節點(參見:在既存集羣中添加節點)

3.        使用nodetool removenode命令根據記錄的死亡節點的HOST ID從集羣中移除死掉的節點。

 Ø  移除數據中心

1.        確認沒有client正在向數據中心內的任何節點寫數據

2.        在數據中心內的各節點中執行nodetool repair以確保數據從該中心得到正確的傳播。更改所有的keyspace屬性確保不再引用即將移除的數據中心。

3.        在數據中心內的各節點分別運行nodetool decommission

9備份恢復

Cassandra通過爲磁盤中的數據文件(SSTable文件)創建快照來備份數據。可爲單個表、單個keyspace、所有keyspace創建快照。可用並行SSH工具爲整個集羣創建快照。創建時不保證所有replica一致,但在恢復快照時Cassandra利用內建的一致性機制保持一致性。創建了系統範圍的快照後可開啓增量備份只備份自上次快照以來變化了的數據(每當一個SSTable被flush後,一個對應的硬鏈接被拷貝至與/snapshot同級的/backups子目錄(需使用JNA))。

 若在Cassandra中使用了JNA,則快照通過硬鏈接創建。否則會因將文件拷貝至不同的位置而增加磁盤I/O。

9.1創建快照

在每個節點執行nodetoolsnapshot命令爲節點創建快照。也可通過並行SSH工具(如pssh)運行nodetool snapshot創建全局的快照。

$ nodetool -h localhost -p 7199 snapshot demdb

 執行命令後首先會將內存中的數據刷進磁盤,之後爲每個keyspace的SSTable文件創建硬鏈接。快照的默認位置爲/var/lib/cassandra/data/<keyspace_name>/<table_name>/snapshots。其中/var/lib/cassandra/data部分依據數據目錄設置而不同。

 要保證空間充足,創建後可考慮移至其他位置。

9.2刪除快照

創建新的快照並不會自動刪除舊的快照,需在創建新快照前通過nodetool clearsnapshot命令移除舊的快照。

$ nodetool -h localhost -p 7199 clearsnapshot

 同樣可通過並行SSH工具(如pssh)運行nodetoolclearsnapshot一次刪除所有節點的快照。

9.3啓用增量備份

默認不開啓,可通過在各節點的cassandra.yaml配置文件中設置incremental_backups爲true來開啓增量備份。開啓後會爲每個新的被刷入的SSTable創建一個硬鏈接並拷貝至數據目錄的/backups子目錄。

 Cassandra不會自動刪除增量備份文件,創建新的快照前需手工移除舊的增量備份文件。

9.4從快照恢復數據

需所有的快照文件,若使用了增量備份還需快照創建之後所有的增量備份文件。通常,在從快照恢復數據前需先truncate表。(若備份發生在delete前而恢復發生在delete後且沒truncate表時,則不能得到最原始的數據,因爲直到compaction操作發生前被標記爲tombstone的數據與原始數據處於不同的SSTable中,所以恢復包含原始數據的SSTable不會移除被標記被tombstone的數據,這些數據仍然顯示爲將被刪除)。

 可以用如下方式從快照恢復數據

Ø  使用sstableloader工具

http://www.datastax.com/documentation/cassandra/2.0/webhelp/cassandra/tools/toolsBulkloader_t.html

Ø  先拷貝snapshot目錄中的快照文件至相應數據目錄。之後通過JConsole調用column family MBean 中的JMX方法loadNewSSTables()或者使用nodetool refresh命令而不調用上述方法。

Ø  使用重啓節點的方式

1.        若恢復單節點則先關閉該節點,若恢復整個集羣則需先關閉所有節點

2.        清除/var/lib/cassandra/commitlog中的所有文件

3.        刪除<data_directory_location>/<keyspace_name>/<table_name>中所有*.db文件

4.        拷貝最新<data_directory_location>/<keyspace_name>/<table_name>/snapshots/<snapshot_name>的快照文件至<data_directory_location>/<keyspace_name>/<table_name>/snapshots/<snapshot_name>

5.        若使用了增量備份則還需拷貝<data_directory_location>/<keyspace_name>/<table_name>/backups中的內容至<data_directory_location>/<keyspace_name>/<table_name>

6.        重啓節點

7.        運行nodetool repair

10工具

Ø  nodetool:管理Cassandra集羣的命令行工具

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsNodetool_r.html

 Ø  sstableloader:載入大量外部數據至一集羣;將已經存在的SSTable載入到另外一個節點數不同或者複製策略不同的集羣;從快照恢復數據。上述操作無需停機。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsBulkloader_t.html

Ø  cassandra:啓動cassandra 服務器進程

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsCUtility_t.html

Ø  cassandra-stress:基於java的Cassandra集羣壓力測試工具。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsCStress_t.html

Ø  cassandra-shuffle:在不停機的狀態下將single-token-per-node的結構轉化爲使用虛擬節點的結構。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsCassandraShuffle.htm

Ø  sstablescrub:清洗指定的表的SSTable。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsSSTableScrub_t.html

Ø  sstable2json/json2sstable:前者將磁盤中表示表的SStable轉化爲JSON格式的文檔,用於調試和測試目的;後者做反向轉換。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsSStable2json_t.html

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsJson2sstable_t.html

Ø  sstablekeys:sstable2json  –e 的縮寫,僅作用於key。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsSStabkeys_t.html

Ø  sstableupgrade:將特定表中或快照中的SSTable升級至匹配當前Cassandra版本。

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/ToolsSSTableupgrade_t.html

參考

http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html


轉載於:https://my.oschina.net/moks/blog/526651

相關文章
相關標籤/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。