《日子》.Cassandra研究報(bào)告

1基本安裝
1.1在基于RHEL的系統(tǒng)中安裝Cassandra
1.1.1必要條件
? YUM包管理器
? Root或sudo權(quán)限
? JRE6或者JRE7
? JNA(Java native Access)(生產(chǎn)環(huán)境需要)
1.1.2步驟
? 安裝配置JRE(略)
? 添加軟件包倉(cāng)庫(kù)到Y(jié)UM的軟件庫(kù)
將以下內(nèi)容添加進(jìn)/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
經(jīng)過(guò)上述步驟即安裝好了Cassandra,隨后便可對(duì)其進(jìn)行配置。以此方式安裝的Cassandra會(huì)創(chuàng)建一個(gè)名為cassandra的用戶,cassandra以此用戶啟動(dòng)服務(wù)。
1.2在任意基于Linux的系統(tǒng)中安裝Cassandra
1.2.1必要條件
? JRE6或者JRE7
? JNA(Java native Access) (生產(chǎn)環(huán)境需要)
1.2.2步驟
? 安裝配置JRE(略)
? 下載Cassandra二進(jìn)制 tarball
http://planetcassandra.org/Download/StartDownload頁(yè)面手工下載對(duì)應(yīng)版本的Cassandra,或者通過(guò)curl -OLhttp://downloads.datastax.com/community/dsc.tar.gz命令自動(dòng)下載最新的DataStaxCommunity,也可由http://cassandra.apache.org/download/頁(yè)面手工下載對(duì)應(yīng)版本。
? 解壓tarball
tar –xzvf dsc-cassandra-2.0.0-bin.tar.gz
根據(jù)下載的版本也可能是:tar –xzvf apache-cassandra-2.0.0-bin.tar.gz
? 安裝配置JNA
2 下載jna.jar(https://github.com/twall/jna/ )。
2 將下載的jna.jar添加進(jìn)Cassandra安裝目錄的lib目錄下或?qū)⑵涮砑舆M(jìn)CLASSPATH環(huán)境變量中
2 在/etc/security/limits.conf文件中加入如下行:
$USER soft memlock unlimited
$USER hard memlock unlimited
其中$USER為運(yùn)行cassandra的用戶
? 創(chuàng)建數(shù)據(jù)目錄和日志目錄并指定給用于運(yùn)行cassandra服務(wù)的具有相應(yīng)讀寫權(quán)限的用戶
$ 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配置文件中默認(rèn)使用上述目錄分別作為數(shù)據(jù)目錄和日志目錄,可創(chuàng)建不同的目錄,賦予對(duì)應(yīng)的權(quán)限,并在配置文件中重新指定以改變默認(rèn)行為。
至此已安裝好了Cassandra,隨后便可對(duì)其進(jìn)行配置。
1.3在其他平臺(tái)安裝Cassandra(略)
1.5通過(guò)源碼構(gòu)建Cassandra(略)
2簡(jiǎn)單配置
Cassandra的主配置文件為cassandra.yaml,其位置隨Cassandra安裝方式不同而不同。
? 對(duì)于CassandraPackage安裝:/etc/cassandra/conf
? 對(duì)于CassandraBinary安裝:<install_location>/conf
? 對(duì)于DataStaxEnterprise Packaged安裝:/etc/dse/cassandra
? 對(duì)于DataStaxEnterpriseBinary安裝:<install_location>/resources/cassandra/conf
配置文件中的配置參數(shù)被分為如下幾個(gè)組
? Initialization properties:控制集群內(nèi)的節(jié)點(diǎn)如何配置,包括節(jié)點(diǎn)間通訊,數(shù)據(jù)分區(qū)及復(fù)制布置。
? Global row and key caches properties:用于緩存表的參數(shù)的配置參數(shù)。
? Performance tuning properties:調(diào)整性能和系統(tǒng)資源的利用,包括內(nèi)存、磁盤I/O、CPU、讀和寫。
? Binary and RPC protocol timeout properties:用于二進(jìn)制協(xié)議的超時(shí)設(shè)置。
? Remote procedure call tuning(RPC)properties:用于配置和調(diào)整RPCs(客戶端連接)
? Fault detection properties:用于處理運(yùn)行情況較差或者失敗的節(jié)點(diǎn)。
? Automatic backup properties:用于自動(dòng)化備份。
? Security properties:用于服務(wù)器端和客戶端的安全設(shè)置
每個(gè)組包都含若干具體的參數(shù)(具體內(nèi)容可參考:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/configuration/configCassandra_yaml_r.html
例如,對(duì)于新安裝的Cassandra可能會(huì)修改配置文件中的下面幾個(gè)參數(shù)
? data_file_directories:數(shù)據(jù)目錄,對(duì)于包方式(如deb或rpm)安裝的Cassandra,該目錄會(huì)在安裝過(guò)程中自動(dòng)創(chuàng)建并具有正確的權(quán)限,默認(rèn)位置為/var/lib/cassandra/data。
? commitlog_directory:commit log目錄,對(duì)于包方式安裝的Cassandra,該目錄會(huì)在安裝過(guò)程中自動(dòng)創(chuàng)建并具有正確的權(quán)限,默認(rèn)位置為/var/lib/cassandra/commitlog。
? saved_caches_directory:保存的緩存目錄,對(duì)于包方式安裝的Cassandra,該目錄會(huì)在安裝過(guò)程中自動(dòng)創(chuàng)建并具有正確的權(quán)限,默認(rèn)位置為/var/lib/cassandra/saved_caches。
如果以二進(jìn)制方式或源碼方式安裝Cassandra需自行創(chuàng)建相應(yīng)目錄,賦予正確的權(quán)限。又或者不想使用默認(rèn)的位置,也可以自行創(chuàng)建新的目錄,賦予正確的權(quán)限,并在配置文件中指定。比如:
data_file_directories:/data/cassandra/data
commitlog_directory:/data/cassandra/commitlog
saved_caches_directory:/data/cassandra/saved_caches
另外,對(duì)于包方式安裝的Cassandra,還會(huì)在安裝過(guò)程中自動(dòng)創(chuàng)建/var/log/cassandra目錄并賦予正確的權(quán)限。默認(rèn)情況下Cassandra將其日志寫進(jìn)該目錄的system.log文件中??赏ㄟ^(guò)修改log4j-server.properies文件(與cassandra.yaml位于同一目錄)中的log4j.appender.R.File來(lái)改變默認(rèn)行為,比如:log4j.appender.R.File=/data/cassandra/system.log
還可能要修改JVM級(jí)別的參數(shù),該部分的參數(shù)可在cassandra-env.sh文件(與cassandra.yaml位于同一目錄)中設(shè)置。
3啟動(dòng)及簡(jiǎn)單使用
3.1啟動(dòng)Cassandra
對(duì)于二進(jìn)制包安裝方式
? 執(zhí)行bin/cassandra–f,前臺(tái)啟動(dòng)cassandra,cassandra會(huì)將日志輸出到標(biāo)準(zhǔn)輸出中。若沒(méi)在輸出中看到“error”、“fatal”或者類似“java stack trace”的內(nèi)容表明cassandra可正常工作??赏ㄟ^(guò)“Control-C“停止casandra。
? 執(zhí)行bin/cassandra,后臺(tái)啟動(dòng)cassandra。
? 可通過(guò)kill或pkill命令停止cassandra
對(duì)于YUM安裝方式
? 執(zhí)行sudoservice Cassandra start啟動(dòng)cassandra
? 執(zhí)行sudoservice Cassandra stop 停止cassandra
3.2使用cqlsh
執(zhí)行bin/cqlsh,出現(xiàn)如下提示則表明連接成功(需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,命令默認(rèn)以“;”結(jié)束。
查看keyspace
DESCRIBEkeyspaces;
創(chuàng)建keyspace
CREATEKEYSPACE mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy','replication_factor' : 2 };
切換keyspace
USE mykeyspace;
創(chuàng)建表
CREATE TABLEusers (
user_id int PRIMARY KEY,
fname text,
lname text
);
查看表
DESCRIBETABLES;
插入數(shù)據(jù)
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');
查詢數(shù)據(jù)
SELECT * FROMusers;
建立索引后使用WHERE從句查找
CREATE INDEXON users (lname);
SELECT * FROMusers WHERE lname = 'smith';
刪除表
DROP TABLEusers;
至此已經(jīng)擁有了單節(jié)點(diǎn)的Cassandra,且能夠通過(guò)cqlsh連接至cassandra并使用CQL執(zhí)行操作。下面對(duì)Cassandra作進(jìn)一步介紹。
4搭建集群
4.1單數(shù)據(jù)中心集群
4.1.1前置工作
? 在每個(gè)節(jié)點(diǎn)上裝配Cassandra
? 為集群確定名稱
? 獲取每個(gè)節(jié)點(diǎn)的IP
? 確定用來(lái)做種子的節(jié)點(diǎn)(Cassandra通過(guò)種子節(jié)點(diǎn)來(lái)找到彼此并了解環(huán)的拓?fù)洌?br> ? 確定snitch(用于確定向/從哪個(gè)數(shù)據(jù)中心和網(wǎng)架寫入/讀取數(shù)據(jù)。有不同的類型可選,具體參考:http://www.datastax.com/documentation/cassandra/2.0/webhelp/cassandra/architecture/architectureSnitchesAbout_c.html
4.1.2具體配置
1.假定使用以下已經(jīng)安裝了Cassandra的節(jié)點(diǎn)配置集群(資源有限,這里只用兩臺(tái)機(jī)器來(lái)說(shuō)明過(guò)程。真實(shí)環(huán)境下最好是有多臺(tái)機(jī)器,且一個(gè)集群中最好有一個(gè)以上的種子)
node0192.168.83.35 (seed)
node1192.168.83.37
2.假定節(jié)點(diǎn)所在機(jī)器有防火墻,注意開(kāi)放Cassandra所使用的端口(相關(guān)端口可查http://www.datastax.com/documentation/cassandra/2.0/webhelp/cassandra/security/secureFireWall_r.html
3.若Cassandra正運(yùn)行則先關(guān)閉,后清除數(shù)據(jù)。
$ sudo servicecassandra stop
或者(根據(jù)安裝方式而不同)
$ ps auwx |grep cassandra
$ sudo kill <pid>
4.清除數(shù)據(jù)
$ sudo rm -rf/var/lib/cassandra/*
5.修改cassandra.yaml文件中的相應(yīng)內(nèi)容
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
    若是建立全新的還不包含數(shù)據(jù)的集群則加上auto_bootstrap:false
    6.剩余節(jié)點(diǎn)的配置與除了listen_address應(yīng)當(dāng)為自身IP外,其他配置與上述相同
    7.先啟動(dòng)逐個(gè)啟動(dòng)seed節(jié)點(diǎn),再逐個(gè)啟動(dòng)剩余節(jié)點(diǎn)
    $ sudo servicecassandra start
    或者
    $ cd<install_location>
    $ bin/Cassandra
    8.使用nodetoolstatus命令查看集群是否成功運(yùn)行
    4.2多數(shù)據(jù)中心集群
    這里,數(shù)據(jù)中心指的就是一組節(jié)點(diǎn),與復(fù)制組是同義詞。多數(shù)據(jù)中心集群中,數(shù)據(jù)可以在不同數(shù)據(jù)中心間自動(dòng)、透明復(fù)制。
    4.2.1前置工作
    與單節(jié)點(diǎn)集群配置基本相同,不同的是還需要確定數(shù)據(jù)中心和網(wǎng)架的命名。
    4.2.2具體配置
    1.假定在以下已經(jīng)安裝了Cassandra的節(jié)點(diǎn)配置集群
    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.若如防火墻,則先開(kāi)放相應(yīng)端口(同上)
    3.若Cassandra正運(yùn)行則先關(guān)閉(同上)
    4.清除數(shù)據(jù)(同上)
    5.修改cassandra.yaml文件中的相應(yīng)內(nèi)容
    …同上…
    endpoint_snitch:PropertyFileSnitch
    若是建立全新的還不包含數(shù)據(jù)的集群則加上auto_bootstrap:false
    6.剩余節(jié)點(diǎn)的配置與除了listen_address應(yīng)當(dāng)為自身IP外,其他配置與上述相同
    7.步驟5中指定endpoint_snitch為PropertyFileSnitch所以要編輯對(duì)應(yīng)的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
之后還要為位置的節(jié)點(diǎn)設(shè)置一個(gè)默認(rèn)的數(shù)據(jù)中心和網(wǎng)架名

default forunknown nodes

default=DC1:RAC1
8.逐個(gè)啟動(dòng)種子節(jié)點(diǎn),之后逐個(gè)啟動(dòng)剩余節(jié)點(diǎn)(同上)
9.驗(yàn)證環(huán)是否成功啟動(dòng)(同上)
5使用CQL
CQL:CassandraQuery Language
激活CQL:cqlsh、DataStaxJava Driver、Thrift方法set_cql_version、Python驅(qū)動(dòng)中的connect()調(diào)用。
使用cqlsh
bin/cqlsh hostport –u username –p password
創(chuàng)建keyspace
keyspace為表命名空間,指明節(jié)點(diǎn)中數(shù)據(jù)如何復(fù)制,一般一個(gè)應(yīng)用對(duì)應(yīng)一個(gè)keyspace。cassandra中的復(fù)制控制以單個(gè)keyspace為基礎(chǔ)。
CREATEKEYSPACE demodb WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor': 3};
class指明復(fù)制策略,replication_factor指明復(fù)制的份數(shù)
使用keyspace
USE demodb;
更新keyspace
ALTER KEYSPACEdemodb WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 2};
ALTER KEYSPACEdemodb WITH REPLICATION ={'class' : 'NetworkTopologyStrategy', 'dc1' : 3, 'dc2': 2};
之后在每個(gè)受影響的節(jié)點(diǎn)執(zhí)行nodetoolrepair demodb
創(chuàng)建表
use demodb
CREATE TABLEusers (
user_name varchar,
password varchar,
gender varchar,
session_token varchar,
state varchar,
birth_year bigint,
PRIMARY KEY (user_name));
使用復(fù)合primary key創(chuàng)建表
CREATE TABLEemp (
empID int,
deptID int,
first_name varchar,
last_name varchar,
PRIMARY KEY (empID, deptID));
插入數(shù)據(jù)
INSERT INTOemp (empID, deptID, first_name, last_name) VALUES (104, 15, 'jane', 'smith');
** 查詢表(以系統(tǒng)表為例)**
system是Cassandra的系統(tǒng)庫(kù),當(dāng)前含schema_keyspaces、local、peers、schema_columns和schema_columnfamilies幾個(gè)表,分別包含keyspace信息,本地節(jié)點(diǎn)信息、集群節(jié)點(diǎn)信息、columns信息和columnfamilies信息
use system
SELECT * from schema_keyspaces;獲取到當(dāng)前節(jié)點(diǎn)中的eyspace
SELECT * FROMpeers獲取節(jié)點(diǎn)所在集群信息
提取并排序查詢結(jié)果
SELECT * FROMemp WHERE empID IN (103,104) ORDER BY deptID DESC;
使用keyspace限定符
經(jīng)常使用USE keyspacename來(lái)切換keyspace可能不方便,可使用keyspace限定符指定表所屬的keyspace,如
SELECT * fromsystem.schema_keyspaces;
可在ALTER TABLEC、REATE TABLE、DELETE、INSERT、SELECT、TRUNCATE、UPDATE中使用
指定column的過(guò)期時(shí)間
INSERT INTOemp (empID, deptID, first_name, last_name) VALUES (105, 17, 'jane', 'smith')USING TTL 60;
其中USING TTL 60指明該條數(shù)據(jù)60秒后過(guò)期,屆時(shí)會(huì)被自動(dòng)刪除。另外指定了TTL的數(shù)據(jù)columns會(huì)在compaction和repair操作中被自動(dòng)刪除。指定TTL會(huì)有8字節(jié)額外開(kāi)銷。
查詢過(guò)期時(shí)間
SELECT TTL(last_name)from emp;
更新過(guò)期時(shí)間
INSERT INTOemp (empID, deptID, first_name, last_name) VALUES (105, 17, 'miaomiao', 'han')USING TTL 3600;也即,以新的TTL重插一遍數(shù)據(jù)即可。(指定插入的整條數(shù)據(jù)的過(guò)期時(shí)間)
或者UPDATA emp USINGTTL 3600 SET last_name='han' where empid=105 and deptid=17; (指定set指明的數(shù)據(jù)的過(guò)期時(shí)間)
查詢寫入時(shí)間
SELECTWRITETIME(first_name) from emp;可查的該數(shù)據(jù)何時(shí)被插入。
添加columns
ALTER TABLEemp ADD address varchar;
更改column數(shù)據(jù)類型
ALTER TABLEemp ALTER address TYPE text;
移除數(shù)據(jù)
2 指定過(guò)期時(shí)間(同上)
2 刪除table或keyspace
DROP TABLE table_name
DROP KEYSPACE keyspace_name;
2 刪除columns和rows
DELETE last_name FROM emp WHEREempid=104 and deptid=15;
DELETE FROM emp WHERE empid=104 anddeptid=15;
使用collection類型
2 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', {'f@baggins.com', 'baggins@gmail.com'});
n UPDATE users SET emails = emails + {'fb@friendsofmordor.org'} WHEREuser_id = 'frodo';
n UPDATE users SET emails = emails - {'fb@friendsofmordor.org'} WHEREuser_id = 'frodo';
n UPDATE users SET emails = {} WHERE user_id = 'frodo';
n DELETE emails FROM users WHERE user_id = 'frodo';
2 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';
2 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';
注;可為上述三種集合類型的每個(gè)元素設(shè)置單獨(dú)的過(guò)期時(shí)間。
創(chuàng)建和使用索引
CREATE INDEXlast_name_key ON users(last_name);
SELECT * FROMusers WHERE last_name = 'Baggins'(需創(chuàng)建了索引才能在WHERE中使用該列進(jìn)行查詢,暫無(wú)多列索引,需逐列分別建立索引)
輕量級(jí)事務(wù)
使用IF從句實(shí)現(xiàn)
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
用于記錄特定時(shí)間或處理的次數(shù)。對(duì)應(yīng)的column需使用counter數(shù)據(jù)類型,該類數(shù)據(jù)一般存儲(chǔ)于專門的表中,且使用UPDATE載入并增減counter值,不使用INSERT插入counter值。只能在原數(shù)值的基礎(chǔ)上增減,不能為直接指定一個(gè)數(shù)值。
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';
若原來(lái)不存在WHERE條件中指定的內(nèi)容,該條語(yǔ)句會(huì)將表中的url_name值置為'www.datastax.com'將page_name置為’home’,將counter_value指定為默認(rèn)初始值0加1。若WHERE條件中指定的內(nèi)容存在,則將counter_value置為原來(lái)的counter_value加1
UPDATEcounterks.page_view_counts
SET counter_value = counter_value + 2
WHERE url_name='www.baidu.com' ANDpage_name='map';
更多CQL內(nèi)容請(qǐng)參見(jiàn):http://www.datastax.com/documentation/cql/3.1/webhelp/index.html
6安全
三方面安全策略
? Client-to-node/node-to-node加密(SSL):加密傳輸?shù)臄?shù)據(jù)
? 基于登錄賬戶/密碼的認(rèn)證:確定誰(shuí)可以使用數(shù)據(jù)庫(kù)
? 對(duì)象授權(quán)管理:確定用戶可在在數(shù)據(jù)庫(kù)上干什么
6.1 SSL加密
6.1.1Client-to-node
準(zhǔn)備證書
? 為每個(gè)節(jié)點(diǎn)產(chǎn)生私鑰/公鑰對(duì)
keytool-genkey -alias cassandra_vms00780 -keystore ~/keys/.keystore
? 導(dǎo)出公鑰部分到單獨(dú)的證書文件,并拷貝該文件到其他所有節(jié)點(diǎn)
keytool-export -alias cassandra_vms00780 -file ~keys/cassandra_vms00780.cer -keystore ~/keys/.keystore
? 將每個(gè)節(jié)點(diǎn)的證書添加到所有節(jié)點(diǎn)的信任庫(kù)中
keytool-import -v -trustcacerts -alias cassandra_vms00780 -file cassandra_vms00780.cer–keystore ~/keys/ .truststore
? 保證將.keystore和truststore文件分發(fā)到所有節(jié)點(diǎn)
? 確認(rèn).keystore文件只對(duì)Cassandradaemon可讀
編輯配置文件
配置cassandra.yaml文件中client_encryption_options部分的參數(shù)
client_encryption_options:
enabled: true
keystore: ~keys/.keystore## .keystore file路徑
keystore_password:<keystore password> ## 產(chǎn)生keystore時(shí)用的密碼
truststore: ~keys/.truststore
truststore_password:<truststore password>
require_client_auth:<true or false>
6.1.2node-to-node
準(zhǔn)備證書
同上
編輯配置文件
配置cassandra.yaml文件中server_encryption_options部分的參數(shù)
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
可在主目錄依據(jù)樣例文件cqlshrc.sample創(chuàng)建.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內(nèi)部認(rèn)證
基于Cassandra控制的登錄賬戶和密碼
認(rèn)證用的登錄名和經(jīng)bcrypt散列的密碼存儲(chǔ)于system_auth.credentials表中
6.2.1配置
第一步
? 若要使用基于用戶名/密碼的認(rèn)證機(jī)制,需要先配置cassandra.yaml文件中authenticator的值為PasswordAuthenticator(該參數(shù)默認(rèn)值為AllowAllAuthenticator,即,不進(jìn)行任何認(rèn)證)。這樣cassandra會(huì)在system_auth.user創(chuàng)建一個(gè)超級(jí)用戶,用戶名和密碼均為cassandra。之后,配置system_auth這個(gè)keyspace的replication factor為較大的值(詳見(jiàn)第5章使用創(chuàng)建、更新keyspace部分的內(nèi)容)
認(rèn)證語(yǔ)句
? ALTER USER
ALTER USERuser_name WITH PASSWORD 'password' (NOSUPERUSER| SUPERUSER)
注:SUPERUSER可更改其他用戶的密碼和SUPERUSER狀態(tài)(NOSUPERUSER或 SUPERUSER),但不能改變自己的SUPERUSER狀態(tài)。普通用戶只能更改自己的密碼。
? CREATE USER
CREATE USERuser_name WITH PASSWORD 'password' (NOSUPERUSER| SUPERUSER)
只有SUPERUSER可創(chuàng)建用戶,創(chuàng)建的用戶默認(rèn)為NOSUPERUSER
? DROP USER
DROP USER user_name
只有SUPERUSER可刪除用戶,用戶不能自己刪除自己。
? LIST USERS
LIST USERS(為什么沒(méi)有結(jié)果???)
列出用戶
更改默認(rèn)SUPERUSER
? 使用默認(rèn)SUPERUSER也即cassandra登錄
./cqlsh -ucassandra -p Cassandra
? 新建另一SUPERUSER,之后刪除原cassandraSUPERUSER
create userus_yanzhaozhang with password 'cassandra' superuser;
drop usercassandra;
? 重啟cassandra,使用新的SUPERUSER登錄,執(zhí)行后續(xù)操作。
6.2.2使用cqlsh登錄
若使用cqlsh登錄,可將認(rèn)證信息存儲(chǔ)于.cqlshrc文本文件,放置在用戶主目錄中,以免重復(fù)錄入登錄信息。注意對(duì)該文本文件設(shè)置對(duì)應(yīng)的權(quán)限以防信息泄露。
[authentication]
username = example_username
password = example_password
6.3內(nèi)部授權(quán)
對(duì)象權(quán)限管理基于內(nèi)部授權(quán),與關(guān)系型數(shù)據(jù)庫(kù)GRANT/REVOKE語(yǔ)法類似。
首先要配置cassandra.yaml中authorizer的值為CassandraAuthorizer(默認(rèn)為AllowAllAuthorizer,允許任何用戶的任何動(dòng)作),設(shè)定為該值后會(huì)將授權(quán)信息存儲(chǔ)在system_auth.permissions表中。
之后,配置system_auth這個(gè)keyspace的replicationfactor為較大的值。
通過(guò)設(shè)置permissions_validity_in_ms選項(xiàng)調(diào)整權(quán)限有效期。
語(yǔ)法
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配置防火墻端口訪問(wèn)
需在防火墻策略中開(kāi)放一下端口
? 公共端口
n 22 ssh端口
n 8888 OpsCenter website端口
? Cassandra節(jié)點(diǎn)間端口
n 1024+ JMX reconnection/loopback端口
n 7000 Cassand集群內(nèi)節(jié)點(diǎn)間通訊端口
n 7199 Cassandra JMX 監(jiān)控端口
n 9160 Cassandra客戶端端口
? Cassandra OpsCenter 端口
n 61620 OpsCenter監(jiān)控端口
n 61621 OpsCenter代理端口
7架構(gòu)
7.1梗概
點(diǎn)對(duì)點(diǎn)分布式系統(tǒng),集群中各節(jié)點(diǎn)平等,數(shù)據(jù)分布于集群中各節(jié)點(diǎn),各節(jié)點(diǎn)間每秒交換一次信息。每個(gè)節(jié)點(diǎn)的commit log捕獲寫操作來(lái)確保數(shù)據(jù)持久性。數(shù)據(jù)先被寫入memtable-內(nèi)存中的數(shù)據(jù)結(jié)構(gòu),待該結(jié)構(gòu)滿后數(shù)據(jù)被寫入SSTable-硬盤中的數(shù)據(jù)文件。所有的寫內(nèi)容被自動(dòng)在集群中分區(qū)并復(fù)制。
Cassandra數(shù)據(jù)庫(kù)面向行。授權(quán)用戶可連接至任意數(shù)據(jù)中心的任意節(jié)點(diǎn),并通過(guò)類似SQL的CQL查詢數(shù)據(jù)。集群中,一個(gè)應(yīng)用一般包含一個(gè)keyspace,一個(gè)keyspace中包含多個(gè)表。
客戶端連接到某一節(jié)點(diǎn)發(fā)起讀或?qū)懻?qǐng)求時(shí),該節(jié)點(diǎn)充當(dāng)客戶端應(yīng)用與擁有相應(yīng)數(shù)據(jù)的節(jié)點(diǎn)間的協(xié)調(diào)者(coordinator)以根據(jù)集群配置確定環(huán)中的哪個(gè)節(jié)點(diǎn)當(dāng)獲取這個(gè)請(qǐng)求。
關(guān)鍵詞
? Gossip:點(diǎn)對(duì)點(diǎn)通信協(xié)議,用以Cassandra集群中節(jié)點(diǎn)間交換位置和狀態(tài)信息。
? Partitioner:決定如何在集群中的節(jié)點(diǎn)間分發(fā)數(shù)據(jù),也即在哪個(gè)節(jié)點(diǎn)放置數(shù)據(jù)的第一個(gè)replica。
? Replica placement strategy:決定在哪些節(jié)點(diǎn)放置數(shù)據(jù)的其他replica。Cassandra在集群中的多個(gè)節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù)的多份拷貝-replicas來(lái)確??煽亢腿蒎e(cuò)。
? Snitch:定義了復(fù)制策略用來(lái)放置replicas和路由請(qǐng)求所使用的拓?fù)湫畔?br> ? cassandra.yaml文件:Cassandra主配置文件
? system:Cassandra的系統(tǒng)keyspace,存放table、keyspace的屬性信息等。而屬性信息可通過(guò)CQL或其他驅(qū)動(dòng)設(shè)置。
7.2節(jié)點(diǎn)間通信
Cassandra使用點(diǎn)對(duì)點(diǎn)通訊協(xié)議gossip在集群中的節(jié)點(diǎn)間交換位置和狀態(tài)信息。gossip進(jìn)程每秒運(yùn)行一次,與至多3個(gè)其他節(jié)點(diǎn)交換信息,這樣所有節(jié)點(diǎn)可很快了解集群中的其他節(jié)點(diǎn)信息。
配置gossip(在cassandra.ymal中設(shè)置)
? cluster_name:節(jié)點(diǎn)所屬集群名,集群中每個(gè)節(jié)點(diǎn)應(yīng)相同。
? listen_address:供其他節(jié)點(diǎn)連接至該節(jié)點(diǎn)的IP地址或主機(jī)名,當(dāng)由localhost設(shè)為公共地址。
? seed_provider:逗號(hào)分隔的IP地址(種子列表),gossip通過(guò)種子節(jié)點(diǎn)學(xué)習(xí)環(huán)的拓?fù)?,集群中各?jié)點(diǎn)種子列表當(dāng)相同。多數(shù)據(jù)中心集群中每個(gè)數(shù)據(jù)中心的種子列表當(dāng)至少包含一個(gè)該中心內(nèi)的節(jié)點(diǎn)。
? storage_port:節(jié)點(diǎn)間通訊端口,集群中各節(jié)點(diǎn)當(dāng)一致。
? initial_token:用于single-node-per-token結(jié)構(gòu),節(jié)點(diǎn)在環(huán)空間只擁有一段連續(xù)的token范圍。
? num_tokens:用于virtual nodes,定義了節(jié)點(diǎn)在環(huán)空間所擁有的隨機(jī)分配的token數(shù)目。
失敗檢測(cè)與恢復(fù)
? gossip可檢測(cè)其他節(jié)點(diǎn)是否正常以避免將請(qǐng)求路由至不可達(dá)或者性能差的節(jié)點(diǎn)(后者需配置為dynamic snitch方可)。
? 可通過(guò)配置phi_convict_threshold來(lái)調(diào)整失敗檢測(cè)的敏感度。
? 對(duì)于失敗的節(jié)點(diǎn),其他節(jié)點(diǎn)會(huì)通過(guò)gossip定期與之聯(lián)系以查看是否恢復(fù)而非簡(jiǎn)單將之移除。若需強(qiáng)制添加或移除集群中節(jié)點(diǎn)需使用nodetool工具。
? 一旦某節(jié)點(diǎn)被標(biāo)記為失敗,其錯(cuò)過(guò)的寫操作會(huì)有其他replicas存儲(chǔ)一段時(shí)間(需開(kāi)啟hinted handoff,若節(jié)點(diǎn)失敗的時(shí)間超過(guò)了max_hint_window_in_ms,錯(cuò)過(guò)的寫不再被存儲(chǔ)。)Down掉的節(jié)點(diǎn)經(jīng)過(guò)一段時(shí)間恢復(fù)后需執(zhí)行repair操作,一般在所有節(jié)點(diǎn)運(yùn)行nodetool repair以確保數(shù)據(jù)一致。
7.3數(shù)據(jù)復(fù)制和分發(fā)
Cassandra中分發(fā)、復(fù)制同時(shí)進(jìn)行。Cassandra被設(shè)計(jì)為點(diǎn)對(duì)點(diǎn)系統(tǒng),會(huì)創(chuàng)建數(shù)據(jù)的多個(gè)副本存儲(chǔ)在集群中的一組節(jié)點(diǎn)中。Cassandra中數(shù)據(jù)被組織為表,由primary key標(biāo)識(shí),primary key決定數(shù)據(jù)將被存儲(chǔ)在哪個(gè)節(jié)點(diǎn)。
需指定的內(nèi)容
Virtual nodes:指定數(shù)據(jù)與物理節(jié)點(diǎn)的所屬關(guān)系
Partitioner:在集群內(nèi)劃分?jǐn)?shù)據(jù)
Replicationstrategy:決定如何處理每行數(shù)據(jù)的replicas
Snitch:定義replicationstrategy放置數(shù)據(jù)的replicas時(shí)使用的拓?fù)湫畔?br> 一致性哈希
表中每行數(shù)據(jù)由primary key標(biāo)識(shí),Cassandra為每個(gè)primarykey分配一個(gè)hash值,集群中每個(gè)節(jié)點(diǎn)擁有一個(gè)或多個(gè)hash值區(qū)間。這樣便可根據(jù)primary key對(duì)應(yīng)的hash值將該條數(shù)據(jù)放在包含該hash值的hash值區(qū)間對(duì)應(yīng)的節(jié)點(diǎn)中。
虛擬節(jié)點(diǎn)
使用虛擬接電視數(shù)據(jù)在集群中的分布


若不使用虛擬節(jié)點(diǎn)則需手工為集群中每個(gè)節(jié)點(diǎn)計(jì)算和分配一個(gè)token。每個(gè)token決定了節(jié)點(diǎn)在環(huán)中的位置以及節(jié)點(diǎn)應(yīng)當(dāng)承擔(dān)的一段連續(xù)的數(shù)據(jù)hash值的范圍。如上圖上半部分,每個(gè)節(jié)點(diǎn)分配了一個(gè)單獨(dú)的token代表環(huán)中的一個(gè)位置,每個(gè)節(jié)點(diǎn)存儲(chǔ)將row key映射為hash值之后落在該節(jié)點(diǎn)應(yīng)當(dāng)承擔(dān)的唯一的一段連續(xù)的hash值范圍內(nèi)的數(shù)據(jù)。每個(gè)節(jié)點(diǎn)也包含來(lái)自其他節(jié)點(diǎn)的row的副本。而是用虛擬節(jié)點(diǎn)允許每個(gè)節(jié)點(diǎn)擁有多個(gè)較小的不連續(xù)的hash值范圍。如上圖中下半部分,集群中的節(jié)點(diǎn)是用了虛擬節(jié)點(diǎn),虛擬節(jié)點(diǎn)隨機(jī)選擇且不連續(xù)。數(shù)據(jù)的存放位置也由row key映射而得的hash值確定,但是是落在更小的分區(qū)范圍內(nèi)。
使用虛擬節(jié)點(diǎn)的好處
? 無(wú)需為每個(gè)節(jié)點(diǎn)計(jì)算、分配token
? 添加移除節(jié)點(diǎn)后無(wú)需重新平衡集群負(fù)載
? 重建死掉的節(jié)點(diǎn)更快
? 改善了在同一集群使用異種機(jī)器
數(shù)據(jù)復(fù)制
Cassandra在多個(gè)節(jié)點(diǎn)中存放replicas以保證可靠性和容錯(cuò)性。replicationstrategy決定放置replicas的節(jié)點(diǎn)。replicas的總數(shù)由復(fù)制因子- replication factor確定,比如因子為2代表每行有兩份拷貝,每份拷貝存儲(chǔ)在不同的節(jié)點(diǎn)中。所有的replicas無(wú)主從之分。replication factor通常不能超過(guò)集群中節(jié)點(diǎn)總數(shù)。然而,可現(xiàn)增加replication facto之后在將節(jié)點(diǎn)增至期望的數(shù)量。當(dāng)replication facto超過(guò)總結(jié)點(diǎn)數(shù)時(shí),寫操作被拒絕,但讀操作可進(jìn)行,只要滿足期望的一致性級(jí)別。
當(dāng)前有兩種可用的復(fù)制策略:
? SimpleStrategy:僅用于單數(shù)據(jù)中心,將第一個(gè)replica放在由partitioner確定的節(jié)點(diǎn)中,其余的replicas放在上述節(jié)點(diǎn)順時(shí)針?lè)较虻暮罄m(xù)節(jié)點(diǎn)中。
? NetworkTopologyStrategy:可用于較復(fù)雜的多數(shù)據(jù)中心。可以指定在每個(gè)數(shù)據(jù)中心分別存儲(chǔ)多少份replicas。在每個(gè)數(shù)據(jù)中心放置replicas的方式類似于SimpleStrategy,但傾向于將replicas放在不同rack,因?yàn)橥籸ack的節(jié)點(diǎn)傾向于同時(shí)失敗。配置每個(gè)數(shù)據(jù)中心分別放置多少replicas時(shí)要考慮兩個(gè)主要方面:(1)可滿足本地讀而非跨數(shù)據(jù)中心讀;(2)失敗場(chǎng)景。兩種常用的配置方式為(1)每個(gè)數(shù)據(jù)中心兩份replicas,(2)每個(gè)數(shù)據(jù)中心3份replicas。當(dāng)然,用于特殊目的的非對(duì)稱配置也是可以的,比如在讀操作較頻繁的數(shù)據(jù)中心配置3份replicas而在用于分析的數(shù)據(jù)中心配置一份replicas。
復(fù)制策略在創(chuàng)建keyspace時(shí)指定,如
CREATEKEYSPACE Excelsior WITH REPLICATION = { 'class' : 'SimpleStrategy','replication_factor' : 3 };
CREATEKEYSPACE "Excalibur" WITH REPLICATION = {'class' :'NetworkTopologyStrategy', 'dc1' : 3, 'dc2' : 2};
其中dc1、dc2這些數(shù)據(jù)中心名稱要與snitch中配置的名稱一致。
7.4Partitioners
在Cassandra中,table的每行由唯一的primarykey標(biāo)識(shí),partitioner實(shí)際上為一hash函數(shù)用以計(jì)算primary key的token。Cassandra依據(jù)這個(gè)token值在集群中放置對(duì)應(yīng)的行。
三種partitioner(在cassandra.yaml中設(shè)置)
? Murmur3Partitioner:當(dāng)前的默認(rèn)值,依據(jù)MurmurHash哈希值在集群中均勻分布數(shù)據(jù)。
? RandomPartitioner:依據(jù)MD5哈希值在集群中均勻分布數(shù)據(jù)。
? ByteOrderedPartitioner:依據(jù)行key的字節(jié)從字面上在集群中順序分布數(shù)據(jù)。(不推薦使用)
Murmur3Partitioner和RandomPartitioner使用token向每個(gè)節(jié)點(diǎn)指派等量的數(shù)據(jù)從而將keyspace中的表均勻分布在環(huán)中,即使不同的表使用不同的primary key。讀寫請(qǐng)求均被均勻的分布。ByteOrderedPartitioner允許通過(guò)primary key順序掃描(可通過(guò)index達(dá)到同樣目的),但已引起如下問(wèn)題(1)較復(fù)雜的負(fù)載均衡,(2)順序的寫易導(dǎo)致熱點(diǎn),(3)多表不均勻的負(fù)載均衡。
注意:若使用虛擬節(jié)點(diǎn)(vnodes)則無(wú)需手工計(jì)算tokens。若不使用虛擬節(jié)點(diǎn)則必須手工計(jì)算tokens將所得的值指派給cassandra.ymal主配置文件中的initial_token參數(shù)。具體可參考:http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/architecture/../configuration/configGenTokens_c.html
7.5Snitches
提供網(wǎng)絡(luò)拓?fù)湫畔?,用以確定向/從哪個(gè)數(shù)據(jù)中心或者網(wǎng)架寫入/讀取數(shù)據(jù)。
注意:(1)所有節(jié)點(diǎn)需用相同的snitch;(2)集群中已插入數(shù)據(jù)后由更改了snitch則需運(yùn)行一次fullrepair。
? Dynamic snitching
監(jiān)控從不同replica讀操作的性能,選擇性能最好的replica。dynamic snitch默認(rèn)開(kāi)啟,所有其他snitch會(huì)默認(rèn)使用dynamic snitch 層。
? SimpleSnitch
默認(rèn)值,用于單數(shù)據(jù)中心部署,不使用數(shù)據(jù)中心和網(wǎng)架信息。使用該值時(shí)keyspace復(fù)制策略中唯一需指定的是replication factor
? RackInferringSnitch
根據(jù)數(shù)據(jù)中心和網(wǎng)架確定節(jié)點(diǎn)位置,而數(shù)據(jù)中心及網(wǎng)架信息又有節(jié)點(diǎn)的IP地址隱含指示。
? PropertyFileSnitch
根據(jù)數(shù)據(jù)中心和網(wǎng)架確定節(jié)點(diǎn)位置,而網(wǎng)絡(luò)拓?fù)湫畔⒂钟捎脩舳x的配置文件cassandra-topology.properties 獲取。在節(jié)點(diǎn)IP地址格式不統(tǒng)一無(wú)法隱含指示數(shù)據(jù)中心及網(wǎng)架信息或者復(fù)雜的復(fù)制組中使用該值。需注意的是:(1)配置文件中數(shù)據(jù)中心名需與keyspace中復(fù)制策略中指定的數(shù)據(jù)中心名稱一致;(2)配置文件中需包含集群中任一節(jié)點(diǎn);(3)集群中各節(jié)點(diǎn)內(nèi)cassandra-topology.properties配置文件需相同。
? GossipingPropertyFileSnitch
? 在cassandra-rackdc.properties配置文件中定義本節(jié)點(diǎn)所屬的數(shù)據(jù)中心和網(wǎng)架,利用gossip協(xié)議與其他節(jié)點(diǎn)交換該信息。若從PropertyFileSnitch切至該值,則需逐節(jié)點(diǎn)逐次更新值為GossipingPropertyFileSnitch以確保gossip有時(shí)間傳播信息。
? EC2Snitch
用于部署在Amazon EC2中且所有節(jié)點(diǎn)在單個(gè)區(qū)域中的集群。
? EC2MultiRegionSnitch
? 用于部署在AmazonEC2中,且節(jié)點(diǎn)跨多個(gè)區(qū)域的集群。
7.6客戶端請(qǐng)求
client連接至節(jié)點(diǎn)并發(fā)出read/write請(qǐng)求時(shí),該node充當(dāng)client端應(yīng)用與包含請(qǐng)求數(shù)據(jù)的節(jié)點(diǎn)(或replica)之間的協(xié)調(diào)者,它利用配置的partitioner和replicaplacement策略確定那個(gè)節(jié)點(diǎn)當(dāng)獲取請(qǐng)求。
7.6.1寫請(qǐng)求

協(xié)調(diào)者(coordinator)將write請(qǐng)求發(fā)送到擁有對(duì)應(yīng)row的所有replica節(jié)點(diǎn),只要節(jié)點(diǎn)可用便獲取并執(zhí)行寫請(qǐng)求。寫一致性級(jí)別(write consistency level)確定要有多少個(gè)replica節(jié)點(diǎn)必須返回成功的確認(rèn)信息。成功意味著數(shù)據(jù)被正確寫入了commit log個(gè)memtable。
上例為單數(shù)據(jù)中心,11個(gè)節(jié)點(diǎn),復(fù)制因子為3,寫一致性等級(jí)為ONE的寫情況。
7.6.2多數(shù)據(jù)中心的寫請(qǐng)求

基本同上,但會(huì)在各數(shù)據(jù)中心分別選擇一個(gè)協(xié)調(diào)者以處理該數(shù)據(jù)中心內(nèi)的寫請(qǐng)求。與client直接連接的coordinator節(jié)點(diǎn)只需將寫請(qǐng)求發(fā)送到遠(yuǎn)程數(shù)據(jù)中心的coordinator一個(gè)節(jié)點(diǎn)即可,剩余的由該coordinator完成。若一致性級(jí)別設(shè)置為ONE或者LOCAL_QUORUM則僅與直接協(xié)調(diào)者位于同一數(shù)據(jù)中心的節(jié)點(diǎn)需返回成功確認(rèn)。
上例為雙單數(shù)據(jù)中心,各11個(gè)節(jié)點(diǎn),復(fù)制因子為6,寫一致性等級(jí)為ONE的寫情況。
7.6.3讀請(qǐng)求

? 直接讀請(qǐng)求
? 后臺(tái)讀修復(fù)請(qǐng)求
與直接讀請(qǐng)求聯(lián)系的replica數(shù)目由一致性級(jí)別確定。后臺(tái)讀修復(fù)請(qǐng)求被發(fā)送到?jīng)]有收到直接讀請(qǐng)求的額外的replica,以確保請(qǐng)求的row在所有replica上一致。
協(xié)調(diào)者首先與一致性級(jí)別確定的所有replica聯(lián)系,被聯(lián)系的節(jié)點(diǎn)返回請(qǐng)求的數(shù)據(jù),若多個(gè)節(jié)點(diǎn)被聯(lián)系,則來(lái)自各replica的row會(huì)在內(nèi)存中作比較,若不一致,則協(xié)調(diào)者使用含最新數(shù)據(jù)的replica向client返回結(jié)果。
同時(shí),協(xié)調(diào)者在后臺(tái)聯(lián)系和比較來(lái)自其余擁有對(duì)應(yīng)row的replica的數(shù)據(jù),若不一致,會(huì)向過(guò)時(shí)的replica發(fā)寫請(qǐng)求用最新的數(shù)據(jù)進(jìn)行更新。這一過(guò)程叫read repair。
上例為單數(shù)據(jù)中心,11個(gè)節(jié)點(diǎn),復(fù)制因子為3,一致性級(jí)別為QUORUM的讀情況。
8數(shù)據(jù)庫(kù)內(nèi)部
8.1數(shù)據(jù)管理
使用類似Log-StructuredMerge Tree的存儲(chǔ)結(jié)構(gòu),而非典型的關(guān)系型數(shù)據(jù)庫(kù)使用的B-Tree結(jié)構(gòu)。存儲(chǔ)引擎連續(xù)的將數(shù)據(jù)以追加的模式寫物磁盤并持續(xù)存儲(chǔ)數(shù)據(jù)。節(jié)點(diǎn)間/內(nèi)的操作并行運(yùn)行。因不使用B-Tree故無(wú)需協(xié)同控制,在寫時(shí)不必執(zhí)行更新。Cassandra在SSD中性能表現(xiàn)極佳。
高吞吐量和低延遲
操作并行運(yùn)行,吞吐量和延遲相互獨(dú)立。log-structured設(shè)計(jì)避免詢盤開(kāi)銷。去除on-disk數(shù)據(jù)修改,省時(shí)且延長(zhǎng)SSD壽命。無(wú)on-disk型的數(shù)據(jù)修改故無(wú)需鎖定寫請(qǐng)求這樣的協(xié)同控制。無(wú)主、從,在所有節(jié)點(diǎn)運(yùn)行同樣的代碼。
單獨(dú)的表目錄
/var/lib/cassandra/data/ks1/cf1/ks1-cf1-ja-1-Data.db
其中/var/lib/cassandra/data/為cassandra.yaml中指定的數(shù)據(jù)文件目錄。ks1為keyspace名cf1/為columnfamilies名。這樣可將表連接至選定的目標(biāo)位置以便于將活躍的表移到更快的存儲(chǔ)介質(zhì),或者將表分不到多個(gè)可用的存儲(chǔ)設(shè)備以均衡負(fù)載
8.2關(guān)于寫
復(fù)制的角色
通過(guò)在多個(gè)同級(jí)節(jié)點(diǎn)創(chuàng)建數(shù)據(jù)的多個(gè)副本保證可靠性和容錯(cuò)。表是非關(guān)系型的,無(wú)需過(guò)多額外工作來(lái)維護(hù)關(guān)聯(lián)的表的完整性,因此寫操作較關(guān)系型數(shù)據(jù)庫(kù)快很多。
寫過(guò)程
****
先將數(shù)據(jù)寫進(jìn)內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)memtable,同時(shí)追加到磁盤中的commitlog中。表使用的越多,對(duì)應(yīng)的memtable應(yīng)越大,cassandra動(dòng)態(tài)的為memtable分配內(nèi)存,也可自己手工指定。memtable內(nèi)容超出指定容量后memtable數(shù)據(jù)(包括索引)被放進(jìn)將被刷入磁盤的隊(duì)列,可通過(guò)memtable_flush_queue_size配置隊(duì)列長(zhǎng)度。若將被刷入磁盤的數(shù)據(jù)超出了隊(duì)列長(zhǎng)度,cassandra會(huì)鎖定寫。memtable表中的數(shù)據(jù)由連續(xù)的I/O刷進(jìn)磁盤中的SSTable,之后commit log被清空。每個(gè)表有獨(dú)立的memtable和SSTable。
8.3關(guān)于更新、刪除和hinted handoff writes
更新(cassandra中插入重復(fù)的primarykey也被看做是更新操作)



不直接在磁盤中原地更新而是先在memtable進(jìn)行所有的更新。最后更新內(nèi)容被刷入磁盤存儲(chǔ)在新的SSTable中,僅當(dāng)column的時(shí)間戳比既存的column更新時(shí)才覆蓋原來(lái)的數(shù)據(jù)。
刪除
? 不會(huì)立即從磁盤移除刪除的數(shù)據(jù)
被刪除的數(shù)據(jù)會(huì)被tombstone標(biāo)記以指定其狀態(tài),它會(huì)存在一定的時(shí)間(由gc_grace_seconds指定),超出該時(shí)間后compaction進(jìn)程永久刪除該column。
? 若不例行性的執(zhí)行節(jié)點(diǎn)repair操作,被刪除的column可能重新出現(xiàn)
若刪除期間節(jié)點(diǎn)down掉,被標(biāo)記為tombstone的column會(huì)發(fā)送信號(hào)給Cassandra使其重發(fā)刪除請(qǐng)求給該replica節(jié)點(diǎn)。若replica在gc_grace_seconds期間復(fù)活,會(huì)最終受到刪除請(qǐng)求,若replica在gc_grace_seconds之后復(fù)活,節(jié)點(diǎn)可能錯(cuò)過(guò)刪除請(qǐng)求,而在節(jié)點(diǎn)恢復(fù)后立即刪除數(shù)據(jù)。需定期執(zhí)行節(jié)點(diǎn)修復(fù)操作來(lái)避免刪除數(shù)據(jù)重現(xiàn)。
hinted handoff writes
在不要求一致性時(shí)確保寫的高可用,在cassandra.yaml中開(kāi)啟該功能。執(zhí)行write操作時(shí)若擁有對(duì)應(yīng)row的replica down掉了或者無(wú)回應(yīng),則協(xié)調(diào)者會(huì)在本地的system.hints表中存儲(chǔ)一個(gè)hint,指示該寫操作需在不可用的replica恢復(fù)后重新執(zhí)行。默認(rèn)hints保存3小時(shí),可通過(guò)max_hint_window_in_ms改變?cè)撝怠?br> 提示的write不計(jì)入consistencylevel中的ONE,QUORUM或ALL,但計(jì)入ANY。ANY一致性級(jí)別可確保cassandra在所有replica不可用時(shí)仍可接受write,并且在適當(dāng)?shù)膔eplica可用且收到hint重放后該write操作可讀。
移除節(jié)點(diǎn)后節(jié)點(diǎn)對(duì)應(yīng)的hints自動(dòng)移除,刪除表后對(duì)應(yīng)的hints也會(huì)被移除。
仍需定期執(zhí)行repair(避免硬件故障造成的數(shù)據(jù)丟失)
8.4關(guān)于讀
從SSD并行隨機(jī)讀取,延時(shí)極低(不推薦cassandra使用轉(zhuǎn)盤式硬盤)。以partition key讀/寫,消除了關(guān)系型數(shù)據(jù)庫(kù)中復(fù)雜的查詢。
讀SSTable

首先檢查Bloom filter,每個(gè)SSTable都有一個(gè)Bloomfilter,用以在進(jìn)行任何磁盤I/O前檢查請(qǐng)求的partition key對(duì)應(yīng)的數(shù)據(jù)在SSTable中存在的可能性。若數(shù)據(jù)很可能存在,則檢查Partition key cache(Cassandra表partition index的緩存),之后根據(jù)index條目是否在cache中找到而執(zhí)行不同步驟:
? 找到
從compression offset map中查找擁有對(duì)應(yīng)數(shù)據(jù)的壓縮快。
從磁盤取出壓縮的數(shù)據(jù),返回結(jié)果集。
? 未找到
搜索Partition summary(partition index的樣本集)確定index條目在磁盤中的近似位置。
從磁盤中SSTable內(nèi)取出index條目。
從compression offset map中查找擁有對(duì)應(yīng)數(shù)據(jù)的壓縮快。
從磁盤取出壓縮的數(shù)據(jù),返回結(jié)果集。
回顧插入/更新數(shù)據(jù)

讀的過(guò)程


由insert/update過(guò)程可知,read請(qǐng)求到達(dá)某一節(jié)點(diǎn)后,必須結(jié)合所有包含請(qǐng)求的row中的column的SSTable以及memtable來(lái)產(chǎn)生請(qǐng)求的數(shù)據(jù)。

例如,要更新包含用戶數(shù)據(jù)的某個(gè)row中的email 列,cassandra并不重寫整個(gè)row到新的數(shù)據(jù)文件,而僅僅將新的email寫進(jìn)新的數(shù)據(jù)文件,username等仍處于舊的數(shù)據(jù)文件中。上圖中紅線表示Cassandra需要整合的row的片段用以產(chǎn)生用戶請(qǐng)求的結(jié)果。為節(jié)省CPU和磁盤I/O,Cassandra會(huì)緩存合并后的結(jié)果,且可直接在該cache中更新row而不用重新合并。
8.5關(guān)于事務(wù)和協(xié)同控制
不支持RDBMS中具有回滾和鎖定機(jī)制的ACID事務(wù),但提供了一定程度的原子性(行級(jí))、隔離性(行級(jí))、持久性和eventual/tunable 類型的一致性(因不支持連接和外鍵,故不提供ACID場(chǎng)景下的一致性)。
? 原子性
row-level,對(duì)一個(gè)row的插入/更新被當(dāng)做一個(gè)原子操作。不支持要么都做要么都不做的多行插入/更新。不支持在一個(gè)replica上write成功而在其他replica上write失敗的回滾。用時(shí)間戳確定column的最新更新。若多個(gè)session同時(shí)更新同樣的column則使用最近的更新。
? 一致性
l Tuneable一致性
提供partition容錯(cuò)。用戶可以以單個(gè)操作為基礎(chǔ)決定需多少個(gè)節(jié)點(diǎn)接收DML操作或響應(yīng)SELECT操作。
l Linearizable一致性
l 輕量事務(wù)(compare-and-set)的一系列隔離級(jí)別。在tuneable一致性不足以滿足要求時(shí)使用,如執(zhí)行無(wú)間斷的相繼操作或同時(shí)/不同時(shí)運(yùn)行一個(gè)操作產(chǎn)生同樣的結(jié)果。Cassandra2.0使用類似2-phase commit的Paxos consensus協(xié)議實(shí)現(xiàn)Linearizable一致性。(為支持該一致性引入了SERIAL類型的consistency level及在CQL中使用了帶IF從句的輕量事務(wù))
? 隔離性
Cassandra2.0開(kāi)始支持row-level的隔離性。對(duì)行的寫操作在完成之前對(duì)其他用戶不可見(jiàn)。
? 持久性
同時(shí)將數(shù)據(jù)寫入內(nèi)存中的memtable及磁盤中的commit log。服務(wù)器故障時(shí)若memtable尚未刷入磁盤,在故障恢復(fù)后可重放commit log恢復(fù)丟失數(shù)據(jù)。這提供了本地持久性。數(shù)據(jù)在其他節(jié)點(diǎn)的副本加強(qiáng)了持久性。
輕量事務(wù)
Cassandra2.0中引入,彌補(bǔ)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配置數(shù)據(jù)一致性
Cassandra中,一致性級(jí)別可配置,以確定請(qǐng)求的數(shù)據(jù)如何在不同的replica保持一致性,從而平衡響應(yīng)時(shí)間和數(shù)據(jù)精確性。
? 寫一致性
指明在返回確認(rèn)至客戶端前,write操作必須成功的replica數(shù)。
l ANY:write至少在一個(gè)replica成功。即使所有replica 都down掉,在寫hinted handoff后write仍成功。在replica恢復(fù)后該write可讀。
l ONE:write必須成功寫入至少一個(gè)replica的commit log和memtable。
l TWO:至少兩個(gè)****
l THREE:至少三個(gè)****
l QUORUM:至少(replication_factor/ 2) + 1個(gè)****
l LOCAL_QUORUM:至少(replication_factor/ 2) + 1個(gè),且與協(xié)調(diào)者處于同一數(shù)據(jù)中心****
l EACH_QUORUM:所有數(shù)據(jù)中心,至少(replication_factor/ 2) + 1個(gè)
l ALL:全部****
l SERIAL:至少(replication_factor/ 2) + 1個(gè),用于達(dá)成輕量事務(wù)的linearizable consistency
需注意的是:實(shí)際上write還是會(huì)被發(fā)到所有相關(guān)的replica中,一致性級(jí)別只是確定必需要反饋的replica數(shù)。
? 讀一致性
指明在返回?cái)?shù)據(jù)值客戶端前,需要相應(yīng)read請(qǐng)求的相關(guān)replica數(shù)。Cassandra從這些數(shù)量的replica中根據(jù)時(shí)間戳檢查最新的數(shù)據(jù)。級(jí)別同寫一致性。
可通過(guò)cqlsh命令CONSISTENCY設(shè)置keyspace的一致性,也可編程設(shè)置一致性。
9操作
9.1監(jiān)控Cassandra集群
工具:nodetool utility、DataStaxOpsCenter、JConsole
? nodetool utility:Cassandra發(fā)行版附帶的命令行工具,用于監(jiān)控和常規(guī)數(shù)據(jù)庫(kù)操作。一些常用命令如status、cfstats、cfhistograms、netstats、tpstats等。
? DataStax OpsCenter:圖形用戶界面工具,從中央控制臺(tái)監(jiān)控和管理集群中所有節(jié)點(diǎn)。
? JConsole:JMX兼容工具用以監(jiān)控java應(yīng)用程序,提供Overview、Memory、Thread、Classes、VM summary、Mbeans方面的信息。
9.2調(diào)整Bloom filters
Bloom filters用以在執(zhí)行I/O前確定SSTable是否含特定的row。用于index掃描而不用于range掃描。通過(guò)bloom_filter_fp_chance參數(shù)配置其屬性值,范圍為0至1.0(關(guān)閉),值越大則使用的內(nèi)存越少,但也意味著若SSTable由較多碎片則導(dǎo)致較高的磁盤I/O。默認(rèn)值依賴于compaction_strategy類型。值的設(shè)置依賴工作負(fù)荷,如,若需在一特定表上運(yùn)行繁重的scan則需將bloom_filter_fp_chance設(shè)置高一點(diǎn)。
通過(guò)如下語(yǔ)句設(shè)置:
ALTER TABLEaddamsFamily WITH bloom_filter_fp_chance = 0.1;
設(shè)置好后需使用Initiatecompaction或Upgrade SSTables方式之一重新產(chǎn)生Bloom filter。
9.3數(shù)據(jù)緩存
兩類cache:partitionkey cache和row cache
? partition key cache:Cassandra表partition index的cache
? row cache:一個(gè)row首次被訪問(wèn)后整個(gè)row(合并自多個(gè)對(duì)應(yīng)的SSTable及memtable)被放在row cache中以便于后續(xù)對(duì)改row的訪問(wèn)能直接由內(nèi)存獲取數(shù)據(jù)。
對(duì)于很少訪問(wèn)的archive表當(dāng)禁用緩存。
開(kāi)啟與配置cache
? 開(kāi)啟
CREATE TABLEusers (
userid text PRIMARY KEY,
first_name text,
last_name text,
)
WITH caching ='all';
? 配置
在cassandra.yaml中,調(diào)整下列參數(shù);
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
工作原理:

****
第一個(gè)read操作直接命中rowcache,從內(nèi)存取出數(shù)據(jù)。第二個(gè)read操作為命中row cache,但命中partition key cache,并由此整合所有相關(guān)的SSTable及memtable中的片段為請(qǐng)求的row,返回row并寫進(jìn)row cache。
cache使用優(yōu)化建議
? 將很少請(qǐng)求的數(shù)據(jù)或row很長(zhǎng)的數(shù)據(jù)放在cache較小或不使用cache的表中
? 用較多的節(jié)點(diǎn)部署各節(jié)點(diǎn)負(fù)載較輕的集群
? 邏輯上將read稠密的數(shù)據(jù)分開(kāi)在離散的表中
9.4配置memtable吞吐量
可改善write性能。Cassandra在commit logspace threshold超出時(shí)將memtables內(nèi)容刷進(jìn)磁盤創(chuàng)建SSTable。在cassandra.ymal中配置commit log space threshold來(lái)調(diào)整memtable吞吐量。配置的值依賴于數(shù)據(jù)和write負(fù)載。下列兩種情況可考慮增加吞吐量:
? write負(fù)載包含大量在小數(shù)據(jù)集上的更新操作
? 穩(wěn)定持續(xù)的寫操作
9.5Compaction與Compression
9.5.1Compaction
周期性的后臺(tái)進(jìn)程。Compaction期間Cassandra通過(guò)整合row片段合并SSTable、移除過(guò)期的tombstones、重建索引等,并在新SSTable合并完成后移除舊的SSTable。
兩類Compaction
? SizeTieredCompactionStrategy
收集尺寸相近的SSTable合并為一個(gè)較大的SSTable。
? LeveledCompactionStrategy
創(chuàng)建相對(duì)較小的SSTable,尺寸被固定為不同等級(jí)(L0、L1、L2……),同一級(jí)內(nèi)SSTable大小相同,每差一個(gè)等級(jí)尺寸差10倍。SSTable從較小的等級(jí)逐漸合并至較高的等級(jí)。
Compaction操作會(huì)臨時(shí)增加磁盤I/O,但完成后可改善read性能。
開(kāi)啟與配置Compaction
? 使用CQL語(yǔ)句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 }
更多屬性參見(jiàn)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
通過(guò)減少數(shù)據(jù)體積和磁盤I/O來(lái)最大化存儲(chǔ)能力。大大提升讀性能且不會(huì)像傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)中的Compression操作降低write性能。
什么時(shí)候執(zhí)行Compression
適用于擁有大量的row且每個(gè)row與其他row有一樣的column或盡可能多相同的column的表。越相似壓縮比越高,性能提升越明顯。row具有差異較大的column集的表不適于Compression。如Dynamic表。
配置好compression后后續(xù)創(chuàng)建的SSTable被壓縮,之前已經(jīng)存在的SSTable不被立即壓縮直到正常的Cassandracompaction進(jìn)程開(kāi)始??墒褂胣odetool upgradesstables命令強(qiáng)制壓縮既存的SSTable
配置Compression
? 禁用
CREATE TABLEDogTypes (
block_id uuid,
species text,
alias text,
population varint,
PRIMARY KEY (block_id)
)
WITH compression = {'sstable_compression' : '' };
? 開(kāi)啟
CREATE TABLEDogTypes (
block_id uuid,
species text,
alias text,
population varint,
PRIMARY KEY (block_id)
)
WITH compression = {'sstable_compression' : 'LZ4Compressor' };
? 調(diào)整
ALTER TABLECatTypes
WITH compression = { 'sstable_compression' :'DeflateCompressor', 'chunk_length_kb' : 64 }
9.6調(diào)整Java資源
性能下降或內(nèi)存消耗過(guò)多時(shí)需考慮調(diào)整Java資源。有兩個(gè)文件用于Cassandra中環(huán)境設(shè)置:
? comf/cassandra-env.sh:配置JVM
? bin、cassandra-in.sh:配置Cassandra環(huán)境變量
調(diào)整Heap尺寸時(shí)MAX_HEAP_SIZE與HEAP_NEWSIZE要同時(shí)設(shè)置,前者設(shè)置JVM最大heap尺寸,后者設(shè)置新生代的尺寸,新生代尺寸越大垃圾回收暫停時(shí)間越長(zhǎng),反之垃圾回收消耗越大。
當(dāng)前默認(rèn)配置:
系統(tǒng)內(nèi)存

Heap 大小

少于 2GB

系統(tǒng)內(nèi)存的1/2

2GB t到 4GB

1GB

大于 4GB

系統(tǒng)內(nèi)存的1/4,但不會(huì)超過(guò)8GB

heap大小并非越大越好:首先Java6處理8GB以上的垃圾收集的能力會(huì)迅速縮減;其次會(huì)減少操作系統(tǒng)緩存頁(yè)所能使用的內(nèi)存。
Cassandra1.2以后版本Bloomfilter和compression offset map是off-heap的,不算在JVM的heap之內(nèi)。Cassandra2.0后partition summary也是off-heap的。若在Cassandra中使用JNA庫(kù),row cache也會(huì)升級(jí)為off-heap。這些可幫減少heap大小,增強(qiáng)JVM GC性能,從而增加Cassandra高效處理每個(gè)節(jié)點(diǎn)中數(shù)據(jù)的能力。
若GC頻發(fā)發(fā)生且在適度的時(shí)間完成表明JVM GC壓力過(guò)大,此時(shí)需作出增加節(jié)點(diǎn)、降低cache大小、調(diào)整JVM中有關(guān)GC的參數(shù)等補(bǔ)救措施。
JavaManagement Extensions (JMX)提供了管理和監(jiān)控Java應(yīng)用和服務(wù)的各種工具。如JConsole,、the nodetool utility和 DataStax OpsCenter這些JMX兼容工具。
comf/cassandra-env.sh中其他相關(guān)參數(shù)
? com.sun.management.jmxremote.port
? com.sun.management.jmxremote.ssl
? com.sun.management.jmxremote.authenticate
? -Djava.rmi.server.hostname
9.7修復(fù) node
使用nodetool的repair命令,修復(fù)與給定的數(shù)據(jù)范圍相關(guān)的replica間的不一致性。在下屬情形運(yùn)行修復(fù):
? 規(guī)律的、計(jì)劃的集群維護(hù)操作期間(除非沒(méi)有執(zhí)行過(guò)delete)
? 節(jié)點(diǎn)恢復(fù)后
? 在包含較少被訪問(wèn)的數(shù)據(jù)的節(jié)點(diǎn)上
? 在down掉的節(jié)點(diǎn)更新數(shù)據(jù)
運(yùn)行節(jié)點(diǎn)修復(fù)的方針:
? 常規(guī)修復(fù)操作執(zhí)行次數(shù)由gc_grace值硬性規(guī)定。需在該時(shí)間內(nèi)在每個(gè)節(jié)點(diǎn)至少運(yùn)行一次修復(fù)操作。
? 同時(shí)在多于一個(gè)的節(jié)點(diǎn)運(yùn)行常規(guī)修復(fù)時(shí)需謹(jǐn)慎,最好在低峰期規(guī)律運(yùn)行修復(fù)。
? 在很少delete或overwrite數(shù)據(jù)的系統(tǒng)中,可增加gc_grace的值。
修復(fù)操作消耗磁盤I/O,可通過(guò)下述途徑減輕:
? 使用nodetool的compactionthrottling選項(xiàng)。
? 使用nodetoolsnapshot之后從snapshot執(zhí)行修復(fù)。
修復(fù)操作會(huì)導(dǎo)致overstreaming(問(wèn)題源于Cassandra內(nèi)部Merkletrees數(shù)據(jù)結(jié)構(gòu))。比如只有一個(gè)損壞的partition但卻需發(fā)送很多的stream,且若節(jié)點(diǎn)中存在的partition越多問(wèn)題越嚴(yán)重。這會(huì)引起磁盤空間浪費(fèi)和不必要的compaction??墒褂胹ubrange 修復(fù)來(lái)減輕overstreaming。subrange repair只修復(fù)屬于節(jié)點(diǎn)的部分?jǐn)?shù)據(jù)。
9.8添加/移除節(jié)點(diǎn)或數(shù)據(jù)中心
? 在既存集群中添加節(jié)點(diǎn)
以使用vnodes的節(jié)點(diǎn)為例(推薦此種方式,虛擬節(jié)點(diǎn)相關(guān)內(nèi)容見(jiàn)第7節(jié))

  1.    在新節(jié)點(diǎn)安裝Cassandra,關(guān)閉cassandra,清除數(shù)據(jù)。
    
  2.    在cassandra.yaml和cassandra-topology.properties中配置如下屬性:
    

l cluster_name
l listern_address/broadcast_address
l endpoint_snitch
l num_tokens
l seed_provider

  1.    逐個(gè)啟動(dòng)新節(jié)點(diǎn)中的cassandra,不同節(jié)點(diǎn)的初始化之間保持兩分鐘的間隔。可用nodetool netstats監(jiān)控啟動(dòng)和數(shù)據(jù)流處理
    
  2.    待所有新節(jié)點(diǎn)運(yùn)行起來(lái)后逐個(gè)在每個(gè)之前已存在的節(jié)點(diǎn)執(zhí)行nodetool cleanup來(lái)移除不再屬于這些節(jié)點(diǎn)的key。在下一個(gè)節(jié)點(diǎn)執(zhí)行nodetool cleanup前必須等上一個(gè)節(jié)點(diǎn)中的nodetool cleanup結(jié)束。另外cleanup操作可考慮在低峰期進(jìn)行。
    

? 向既存集群中添加數(shù)據(jù)中心
以使用vnodes的節(jié)點(diǎn)構(gòu)成的集群為例

  1.    確保keyspace使用NetworkTopologyStrategy復(fù)制策略
    
  2.    對(duì)于每個(gè)新節(jié)點(diǎn)在cassandra.yaml中設(shè)置如下屬性
    

l auto_bootstrap: false.
l 設(shè)置其他與所屬集群匹配的屬性(參見(jiàn)上一部分:在既存集群中添加節(jié)點(diǎn))

  1.    根據(jù)設(shè)置的snitch類型在各新節(jié)點(diǎn)配置對(duì)應(yīng)的指明網(wǎng)絡(luò)拓?fù)涞呐渲梦募o(wú)需重啟)
    
  2.    確保使用的客戶端不會(huì)自動(dòng)探測(cè)新的節(jié)點(diǎn)。
    
  3.    若使用QUORUM一致性級(jí)別,需檢查L(zhǎng)OCAL_QUORUM或EACH_QUORUM一致性級(jí)別是否滿足多數(shù)據(jù)中心的要求
    
  4.    逐個(gè)在每個(gè)節(jié)點(diǎn)開(kāi)啟cassandra。注意初始化時(shí)間間隔。
    
  5.    所有節(jié)點(diǎn)運(yùn)行起來(lái)后執(zhí)行下列操作
    

? 替換死掉的節(jié)點(diǎn)
以使用vnodes的節(jié)點(diǎn)構(gòu)成的集群為例

  1.    用nodetool status命令確認(rèn)環(huán)中死掉的節(jié)點(diǎn),從輸出中記錄該節(jié)點(diǎn)的HOST ID。
    
  2.    添加并啟動(dòng)新的替代節(jié)點(diǎn)(參見(jiàn):在既存集群中添加節(jié)點(diǎn))
    
  3.    使用nodetool removenode命令根據(jù)記錄的死亡節(jié)點(diǎn)的HOST ID從集群中移除死掉的節(jié)點(diǎn)。
    

? 移除數(shù)據(jù)中心

  1.    確認(rèn)沒(méi)有client正在向數(shù)據(jù)中心內(nèi)的任何節(jié)點(diǎn)寫數(shù)據(jù)
    
  2.    在數(shù)據(jù)中心內(nèi)的各節(jié)點(diǎn)中執(zhí)行nodetool repair以確保數(shù)據(jù)從該中心得到正確的傳播。更改所有的keyspace屬性確保不再引用即將移除的數(shù)據(jù)中心。
    
  3.    在數(shù)據(jù)中心內(nèi)的各節(jié)點(diǎn)分別運(yùn)行nodetool decommission
    

9備份恢復(fù)
Cassandra通過(guò)為磁盤中的數(shù)據(jù)文件(SSTable文件)創(chuàng)建快照來(lái)備份數(shù)據(jù)。可為單個(gè)表、單個(gè)keyspace、所有keyspace創(chuàng)建快照。可用并行SSH工具為整個(gè)集群創(chuàng)建快照。創(chuàng)建時(shí)不保證所有replica一致,但在恢復(fù)快照時(shí)Cassandra利用內(nèi)建的一致性機(jī)制保持一致性。創(chuàng)建了系統(tǒng)范圍的快照后可開(kāi)啟增量備份只備份自上次快照以來(lái)變化了的數(shù)據(jù)(每當(dāng)一個(gè)SSTable被flush后,一個(gè)對(duì)應(yīng)的硬鏈接被拷貝至與/snapshot同級(jí)的/backups子目錄(需使用JNA))。
若在Cassandra中使用了JNA,則快照通過(guò)硬鏈接創(chuàng)建。否則會(huì)因?qū)⑽募截愔敛煌奈恢枚黾哟疟PI/O。
9.1創(chuàng)建快照
在每個(gè)節(jié)點(diǎn)執(zhí)行nodetoolsnapshot命令為節(jié)點(diǎn)創(chuàng)建快照。也可通過(guò)并行SSH工具(如pssh)運(yùn)行nodetool snapshot創(chuàng)建全局的快照。
$ nodetool -h localhost -p 7199 snapshot demdb
執(zhí)行命令后首先會(huì)將內(nèi)存中的數(shù)據(jù)刷進(jìn)磁盤,之后為每個(gè)keyspace的SSTable文件創(chuàng)建硬鏈接。快照的默認(rèn)位置為/var/lib/cassandra/data/<keyspace_name>/<table_name>/snapshots。其中/var/lib/cassandra/data部分依據(jù)數(shù)據(jù)目錄設(shè)置而不同。
要保證空間充足,創(chuàng)建后可考慮移至其他位置。
9.2刪除快照
創(chuàng)建新的快照并不會(huì)自動(dòng)刪除舊的快照,需在創(chuàng)建新快照前通過(guò)nodetool clearsnapshot命令移除舊的快照。
$ nodetool -h localhost -p 7199 clearsnapshot
同樣可通過(guò)并行SSH工具(如pssh)運(yùn)行nodetoolclearsnapshot一次刪除所有節(jié)點(diǎn)的快照。
9.3啟用增量備份
默認(rèn)不開(kāi)啟,可通過(guò)在各節(jié)點(diǎn)的cassandra.yaml配置文件中設(shè)置incremental_backups為true來(lái)開(kāi)啟增量備份。開(kāi)啟后會(huì)為每個(gè)新的被刷入的SSTable創(chuàng)建一個(gè)硬鏈接并拷貝至數(shù)據(jù)目錄的/backups子目錄。
Cassandra不會(huì)自動(dòng)刪除增量備份文件,創(chuàng)建新的快照前需手工移除舊的增量備份文件。
9.4從快照恢復(fù)數(shù)據(jù)
需所有的快照文件,若使用了增量備份還需快照創(chuàng)建之后所有的增量備份文件。通常,在從快照恢復(fù)數(shù)據(jù)前需先truncate表。(若備份發(fā)生在delete前而恢復(fù)發(fā)生在delete后且沒(méi)truncate表時(shí),則不能得到最原始的數(shù)據(jù),因?yàn)橹钡絚ompaction操作發(fā)生前被標(biāo)記為tombstone的數(shù)據(jù)與原始數(shù)據(jù)處于不同的SSTable中,所以恢復(fù)包含原始數(shù)據(jù)的SSTable不會(huì)移除被標(biāo)記被tombstone的數(shù)據(jù),這些數(shù)據(jù)仍然顯示為將被刪除)。
可以用如下方式從快照恢復(fù)數(shù)據(jù)
? 使用sstableloader工具
http://www.datastax.com/documentation/cassandra/2.0/webhelp/cassandra/tools/toolsBulkloader_t.html
? 先拷貝snapshot目錄中的快照文件至相應(yīng)數(shù)據(jù)目錄。之后通過(guò)JConsole調(diào)用column family MBean 中的JMX方法loadNewSSTables()或者使用nodetool refresh命令而不調(diào)用上述方法。
? 使用重啟節(jié)點(diǎn)的方式

  1.    若恢復(fù)單節(jié)點(diǎn)則先關(guān)閉該節(jié)點(diǎn),若恢復(fù)整個(gè)集群則需先關(guān)閉所有節(jié)點(diǎn)
    
  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中的內(nèi)容至<data_directory_location>/<keyspace_name>/<table_name>
    
  6.    重啟節(jié)點(diǎn)
    
  7.    運(yùn)行nodetool repair
    

10工具
? nodetool:管理Cassandra集群的命令行工具
http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsNodetool_r.html
? sstableloader:載入大量外部數(shù)據(jù)至一集群;將已經(jīng)存在的SSTable載入到另外一個(gè)節(jié)點(diǎn)數(shù)不同或者復(fù)制策略不同的集群;從快照恢復(fù)數(shù)據(jù)。上述操作無(wú)需停機(jī)。
http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsBulkloader_t.html
? cassandra:?jiǎn)?dòng)cassandra 服務(wù)器進(jìn)程
http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsCUtility_t.html
? cassandra-stress:基于java的Cassandra集群壓力測(cè)試工具。
http://www.datastax.com/documentation/cassandra/2.0/webhelp/index.html#cassandra/tools/toolsCStress_t.html
? cassandra-shuffle:在不停機(jī)的狀態(tài)下將single-token-per-node的結(jié)構(gòu)轉(zhuǎn)化為使用虛擬節(jié)點(diǎn)的結(jié)構(gòu)。
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轉(zhuǎn)化為JSON格式的文檔,用于調(diào)試和測(cè)試目的;后者做反向轉(zhuǎn)換。
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升級(jí)至匹配當(dāng)前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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容