Cassandra 屬於 column-family 類型的 NoSQL database,特性是 ring cluster network topology,支援類似 SQL 語法的 CQL,適合儲存依照時間排序且scheme固定的大量資料。以下嘗試在 centos 安裝 cassandra。
單一節點
tar zxvf apache-cassandra-2.2.3-bin.tar.gz -C /usr/share
#啟動
/usr/share/apache-cassandra-2.2.3/bin/cassandra
資料會放在
/usr/share/apache-cassandra-2.2.3/data 這個目錄中
系統紀錄放在
/usr/share/apache-cassandra-2.2.3/logs 這個目錄中
然後參考 cassandra Getting Started 的範例,使用 CQL 測試這個 DB。
// 建立資料庫 mykeyspace
CREATE KEYSPACE mykeyspace
WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };
// 使用資料庫
USE mykeyspace;
// 建立 table: users
CREATE TABLE users (
user_id int PRIMARY KEY,
fname text,
lname text
);
// insert 三筆測試資料
INSERT INTO users (user_id, fname, lname)
VALUES (1745, 'john', 'smith');
INSERT INTO users (user_id, fname, lname)
VALUES (1744, 'john', 'doe');
INSERT INTO users (user_id, fname, lname)
VALUES (1746, 'john', 'smith');
// 取得 users 所有資料
SELECT * FROM users;
user_id | fname | lname
---------+-------+-------
1745 | john | smith
1744 | john | doe
1746 | john | smith
(3 rows)
// 針對 lname 建立 index
CREATE INDEX ON users (lname);
// 條件搜尋
SELECT * FROM users WHERE lname = 'smith';
user_id | fname | lname
---------+-------+-------
1745 | john | smith
1746 | john | smith
直接用 kill -9 停止此單一節點的 cassandra 的 process。
ps aux | grep cassandra
kill -9 20109
兩個節點
在兩台機器上,都分別先將單一節點的設定方式做好。記得一定要先以單機方式先啟動一次,否則會出現 Token 錯誤的問題。
使用 /usr/share/apache-cassandra-2.2.3/tools/bin/token-generator,計算這兩個節點在 Murmur3Partitioner 時,token 分別要設定為多少?
[root@server bin]# /usr/share/apache-cassandra-2.2.3/tools/bin/token-generator
Token Generator Interactive Mode
--------------------------------
How many datacenters will participate in this Cassandra cluster? 2
How many nodes are in datacenter #1? ^C[root@kokola bin]# ./token-generator
Token Generator Interactive Mode
--------------------------------
How many datacenters will participate in this Cassandra cluster? 1
How many nodes are in datacenter #1? 2
DC #1:
Node #1: -9223372036854775808
Node #2: 0
然後分別編輯兩台機器上的 /usr/share/apache-cassandra-2.2.3/conf/cassandra.yaml
把
- seeds: "127.0.0.1"
改為
- seeds: "192.168.1.11,192.168.1.12"
把
listen_address: localhost
分別改為各自的 IP: 192.168.1.11,192.168.1.12
listen_address: 192.168.1.11
在 192.168.1.11 增加一行
initial_token: -9223372036854775808
在 192.168.1.12 則改為
initial_token: 0
然後分別啟動兩台機器的 cassandra。
就可以在第二台機器,用 CQL 取得剛剛在單一節點時建立的 mykeyspace
[root@server bin]# ./cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 2.2.3 | CQL spec 3.3.1 | Native protocol v4]
Use HELP for help.
cqlsh> use mykeyspace ;
/usr/share/apache-cassandra-2.2.3/bin/../lib/cassandra-driver-internal-only-2.7.2.zip/cassandra-driver-2.7.2/cassandra/cluster.py:3331: DeprecationWarning: ResponseFuture.result timeout argument is deprecated. Specify the request timeout via Session.execute[_async].
cqlsh:mykeyspace>
cqlsh:mykeyspace> select * from users;
user_id | fname | lname
---------+-------+-------
1745 | john | smith
1744 | john | doe
1746 | john | smith
(3 rows)
可以用 nodetool 查看 cluster 的狀態
[root@server bin]# ./nodetool -h localhost status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 192.168.1.11 68.09 KB 256 ? 53b41601-c145-4c1a-81d1-9b5f8b09ac73 rack1
UN 192.168.1.12 207.75 KB 256 ? 66642998-9179-4b06-b341-e654dc8e8ca6 rack1
service script
以下為 service script,儲存這個檔案到 /etc/init.d/cassandra,chmod 755 後就可以用 service cassandra start 啟動 cassandra。
#!/bin/bash
# chkconfig: 2345 99 01
# description: Cassandra
. /etc/rc.d/init.d/functions
CASSANDRA_HOME=/usr/share/apache-cassandra-2.2.3/
CASSANDRA_BIN=$CASSANDRA_HOME/bin/cassandra
CASSANDRA_NODETOOL=$CASSANDRA_HOME/bin/nodetool
CASSANDRA_LOG=$CASSANDRA_HOME/logs/cassandra.log
CASSANDRA_PID=/var/run/cassandra.pid
CASSANDRA_LOCK=/var/lock/subsys/cassandra
PROGRAM="cassandra"
if [ ! -f $CASSANDRA_BIN ]; then
echo "File not found: $CASSANDRA_BIN"
exit 1
fi
RETVAL=0
start() {
if [ -f $CASSANDRA_PID ] && checkpid `cat $CASSANDRA_PID`; then
echo "Cassandra is already running."
exit 0
fi
echo -n $"Starting $PROGRAM: "
daemon $CASSANDRA_BIN -p $CASSANDRA_PID >> $CASSANDRA_LOG 2>&1
usleep 500000
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch $CASSANDRA_LOCK
echo_success
else
echo_failure
fi
echo
return $RETVAL
}
stop() {
if [ ! -f $CASSANDRA_PID ]; then
echo "Cassandra is already stopped."
exit 0
fi
echo -n $"Stopping $PROGRAM: "
$CASSANDRA_NODETOOL -h 127.0.0.1 decommission
if kill `cat $CASSANDRA_PID`; then
RETVAL=0
rm -f $CASSANDRA_LOCK
echo_success
else
RETVAL=1
echo_failure
fi
echo
[ $RETVAL = 0 ]
}
status_fn() {
if [ -f $CASSANDRA_PID ] && checkpid `cat $CASSANDRA_PID`; then
echo "Cassandra is running."
exit 0
else
echo "Cassandra is stopped."
exit 1
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status_fn
;;
restart)
stop
start
;;
*)
echo $"Usage: $PROGRAM {start|stop|restart|status}"
RETVAL=3
esac
exit $RETVAL
如何用 R 語言連接 cassandra 資料庫
以下簡述如何使用 R 語言連接 cassandra 資料庫。
調整 cassandra 設定,將 rpc server 打開,並重新啟動 cassandra
修改 /usr/share/apache-cassandra-2.2.3/conf/cassandra.yaml,將 rpc server 打開
start_rpc: true
下載 cassandra-jdbc library
到 cassandra-jdbc 網頁,下載 cassandra-jdbc-2.1.1.jar 以及 cassandra-jdbc dependencies,將所有 jar 檔都放在要執行 R 語言的電腦的一個資料夾中。在 R 語言,安裝 RJDBC 套件
install.packages("RJDBC")
R 語言的範例程式
載入 RJDBC library
> library(RJDBC) Loading required package: DBI Loading required package: rJava
載入 Cassandra JDBC driver,以及相關 jars,我是放在 D:/git/system/pkg/cassandra/cassandra-jdbc/libs/ 這個目錄中,要注意目錄最後面的 libs 後面一定要加上 /
> cassdrv <- JDBC("org.apache.cassandra.cql.jdbc.CassandraDriver", list.files("D:/git/system/pkg/cassandra/cassandra-jdbc/libs/",pattern="jar$",full.names=T))
連接到 cassandra
> casscon <- dbConnect(cassdrv, "jdbc:cassandra://192.168.1.11:9160/mykeyspace")
對此 cassandra connection 執行 CQL
> res <- dbGetQuery(casscon, "select * from users limit 10")
取得 CQL 結果
> res user_id fname lname 1 1745 john smith 2 1744 john doe 3 1746 john smith
錯誤訊息
如果在連接 cassandra 時,發生 SQLNonTransientConnectionException,就表示 cassandra server 並沒有打開 rpc server 連接的設定。> casscon <- dbConnect(cassdrv, "jdbc:cassandra://192.168.1.11:9160/mykeyspace") Error in .jcall(drv@jdrv, "Ljava/sql/Connection;", "connect", as.character(url)[1], : java.sql.SQLNonTransientConnectionException: org.apache.thrift.transport.TTransportException: Cannot write to null outputStream
沒有留言:
張貼留言