客户端编程时我们可以注意的:
1、批量读
当我们使用scan顺序读的时候,默认是一个RPC请求返回一条数据,我们可以设置一次返回多条缓存在客户端缓存,比如sn.setCaching(1000);
2、批量写
数据在客户端累计到一定量再发次请求,批量写
table.setWriteBufferSize(1 * 1024 * 1024);
table.setAutoFlush(false);
3、使用filter
使用过滤器,在服务器端就做好过滤再返回数据到客户端,减少网络流量
服务端需要注意到的地方:
1、rowkey的设计尽量短小,数据的持久化文件HFILE是按照KV存储,如果rowkey过长占用空间大,同时memstore缓存也浪费内存。(memstore是keyValues存储,Hfile是keyValue存储?)
2、指定列族参数,比如大多是scan顺序读,可将block设大些,默认块大小是64K,可以设为128,使用bloomfilter提高随机读性能规避一些hfile的读
3、region热点
开始会不断往一个region写,可以预划分region
如果rowkey不可避免会造成热点。
一种方法是在rowkey加哈希前缀 对region server数量取余(考虑后续扩容数量可设为region server数量整数倍),这种情况scan读的时候会比较麻烦,需要客户端计算好各个子范围开启多个线程分别去范围读
例子
0myrowkey-1
0myrowkey-4
1myrowkey-2
1myrowkey-5
0前缀的rowkey会发到一个region server,1前缀的会发到另一个region server,假如现在需要scan myrowkey-1 至 myrowkey-3
区间数据,并行多个区间分别查询 0myrowkey-1 至 0myrowkey-3、1myrowkey-1 至 1myrowkey-3.。。
另一种方法是对rowkey取md5后的前5-6子字符串作为前缀加到原来的rowkey上,这样查询的时候先做一次md5,但没办法scan了
4、memstore提高写性能,blockcache提高读性能,看需求调整,调大一方调小一方,一般加起来占60至70%
5、关闭major compact,手工弄
6、频繁split我们可以改为手工split
比如一开始都是只往一个region里写,只有当region到一定数量才可能负载比较均衡(写请求),这里又出现了个问题,假设各个region大小非常均匀,他们有可能在同一时间split,影响效率,我们可以关闭split,手工split某些region