MySQL Cluster 初用初測小結
基於上篇搭建的環境,驗證一些基本功能和效能需求。這裡先說一下功能使用的問題。OneCoder也是第一次用。摸索著來,僅做一個記錄。
從部署圖就可知道,對資料庫的請求操作發生在SQL節點上。為了達到試驗效果,這裡又追加了一個sql節點。現在叢集環境如下:
在追加的過程中,發現MySQL Cluster對啟動順序要求嚴格,在沒考慮熱部署方案的情況下,必須停止了所有節點,重新按照management->data->sql的順序啟動節點。
現在測試對錶的建立和修改的自動同步:
在任意SQL節點執行:(這裡選擇44.200節點)
create table bigdata_cluster(id int primary key, name varchar(20)) engine=ndbcluster default charset utf8;
建立表,注意表的引擎一定要指定ndbcluster,在201節點檢視
show tables;
發現已經可以同步查詢了。其實本來底層data節點對上層就是透明的,自然可以查到。多sql節點,就可以起到負載均衡的效果。
調整表和資料插入,都跟傳統的MySQL方式相同,不再贅述,同樣也是可以做到實時同步的,這裡也測過了。下面通過JDBC程式碼測試下API操作的效果,同時也想灌入100w的資料,進行一下效率測試和對比。
在測試前,OneCoder先用SQLyog工具,測試了一下資料庫遠端訪問許可權,發現果然沒有。在一個節點grant all了一下以後,卻發現另一個節點仍然無法訪問,搜尋才知,原來MySQL Cluster的使用者許可權預設不是共享的,進行如下設定,在mysql終端執行:
mysql> SOURCE /usr/local/mysql/share/ndb_dist_priv.sql; mysql> CALL mysql.mysql_cluster_move_privileges();
即可完成許可權共享,現在在一個終端設定的許可權就是叢集共享的了。在用SQLYog測試,果然均可以連結了。下面開始開發JDBC連結MySQL的程式碼:</p>
/**
* 向資料庫中插入資料
*
* @param conn
* @param totalRowCount
* @param perRowCount
* @param tableName
* @author lihzh(OneCoder)
* @throws SQLException
* @date 2013-1-17 下午1:57:10
*/
private void insertDataToTable(Connection conn, String tableName,
long totalRowCount, long perRowCount) throws SQLException {
conn.setAutoCommit(false);
long start = System.currentTimeMillis();
String sql = "insert into " + tableName + " VALUES(?,?,?)";
System.out.println("Begin to prepare statement.");
PreparedStatement statement = conn.prepareStatement(sql);
for (int j = 0; j < TOTAL_ROW_COUNT / BATCH_ROW_COUNT; j++) {
long batchStart = System.currentTimeMillis();
for (int i = 0; i < BATCH_ROW_COUNT; i++) {
long id = j * BATCH_ROW_COUNT + i;
String name_pre = String.valueOf(id);
statement.setLong(1, id);
statement.setString(2, name_pre);
statement.setString(3, name_pre);
statement.addBatch();
}
System.out.println("It's up to batch count: " + BATCH_ROW_COUNT);
statement.executeBatch();
conn.commit();
long batchEnd = System.currentTimeMillis();
System.out.println("Batch data commit finished. Time cost: " + (batchEnd - batchStart));
}
long end = System.currentTimeMillis();
System.out.println("All data insert finished. Total time cost: " + (end - start));
}
開始設定BATCH_ROW_COUNT為5w,結果報錯:
java.sql.BatchUpdateException: Got temporary error 233 'Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)' from NDBCLUSTER
意思比較明顯,超過了MaxNoOfConcurrentOperations設定的值。該值預設為:32768。你可以通過修改config.ini裡的配置改變預設值。不過有人提到,修改該值的同事,你也需要修改
MaxNoOfLocalOperations的值,並且建議後者的值超過前者值10%左右(1.1倍)。
這裡為了避免麻煩,我們直接將程式碼的裡預設值調小到2w,再執行程式碼。
Begin to prepare statement.
It's up to batch count: 20000
Batch data commit finished. Time cost: 20483
It's up to batch count: 20000
Batch data commit finished. Time cost: 19768
It's up to batch count: 20000
Batch data commit finished. Time cost: 20136
It's up to batch count: 20000
Batch data commit finished. Time cost: 19958
…….
java.sql.BatchUpdateException: The table 'bigdata_cluster' is full
無語……表滿了。共寫入了88w條資料。每次batch寫入時間穩定。再測試條件查詢耗時:
/**
* 查詢特定的一個或者一組資料,列印查詢耗時
*
* @param conn
* @param tableName
* @author lihzh
* @throws SQLException
* @date 2013-1-17 下午4:46:20
*/
private void searchData(Connection conn, String tableName) throws SQLException {
long start = System.currentTimeMillis();
String sql = "select * from " + tableName + " where name = ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, "300");
ResultSet resultSet = statement.executeQuery();
resultSet.first();
System.out.println("Name is: " + resultSet.getObject("name"));
long end = System.currentTimeMillis();
System.out.println("Query one row from 88w record cost time: " + (end - start));
}
通過另一個sql節點,根據沒有索引的name欄位查詢耗時約1.4s,有索引的id查詢耗時20ms左右。
再新建一個表,發現什麼資料再也無法寫入,看來是資料節點全域性容量限制導致的。修改config.ini檔案中的
DataMemory=80M # How much memory to allocate for data storage
IndexMemory=18M # How much memory to allocate for index storage
# For DataMemory and IndexMemory, we have used the
# default values. Since the "world" database takes up
# only about 500KB, this should be more than enough for
# this example Cluster setup.
分別改為1400和384M。重啟叢集。再通過
ndb_mgm> all report memoryusage
命令檢視使用情況,
似乎恢復了正常。再向新表寫入資料,成功。
測試刪除資料,又遇到提示:
ERROR 1297 (HY000): Got temporary error 233 'Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)' from NDBCLUSTER
看來真的得調整MaxNoOfConcurrentOperations引數的大小了。根據虛擬機器記憶體情況(據說1約需要1kb記憶體。因此10w,大約100m記憶體),調整如下:
MaxNoOfConcurrentOperations=300000
MaxNoOfLocalOperations=330000
重啟,測試刪除11w資料,通過。同時,再次測試向新表寫入100w條資料,以20w為一組,也順利通過了。
It's up to batch count: 200000
Batch data commit finished. Time cost: 268642
It's up to batch count: 200000
Batch data commit finished. Time cost: 241301
It's up to batch count: 200000
Batch data commit finished. Time cost: 209329
It's up to batch count: 200000
Batch data commit finished. Time cost: 207634
It's up to batch count: 200000
Batch data commit finished. Time cost: 241746
All data insert finished. Total time cost: 1168703
目前的使用情況大致如此,接下來OneCoder打算測試一下叢集節點新增和資料自動分割槽讀寫情況。等有了結論在與大家分享。