KVDB是越露收真差固表妒新浪SAE开发的分布式k来自ey-value数据存妒粉钱阿何储服务,用来支持公有云计算平台上的海量key-val继运团ue存储。KV DB支福政关题云王除针持的存储容量很大,对360百科每个用户支持100G的存储空间,可支持1,000,000,000条记录,用户可以用KV DB存放简单数据,如好友粒远席关系等 。
因为传统关系型数据库在分布式来自环境下表现的扩展性不足等缺点,NoSQL的概念渐渐成为业界关注的焦点,越来360百科越多的技术人员也习惯于使用No得款SQL数据库进行日常开发,SAE为了应对这种怀所耐我死钟松响白查新需求,也进行了NoSQL方向的研发。
KVDB是高性能高话现练希权可靠存储,根据我命杨们内部测试,读写都可以达抓升争训到10w qps。KV DB采用一主多从的分布式蒸谈更皇江得架构,SAE提供热备和肥试定期冷备,发生宕机时,会自动切换到健康的DB上。
KVDB的使用非常方便,用户在使用时,只需要先调用init()函数,就可以调用KV的各种读写函数,值得一提的是,因为KV DB的实际存储选择用B+树实现,所以KV 指底源表儿除探针期DB还支持前缀查找。
数据存储:5云豆/GB·天,即0.05元愿由黄志异/GB·天
请求数:0.5云豆/万次,及0.005元/万次
key的最大长度:200字节
value的最标夜初较员须念大长度:4M (默认启用压缩)
mget获取的最大KEY个数:32
pkrget获取的最大KEY个数:100
开发者来自在登录SAE后,在北座负皮群笑货右上角我的应用中选中指定应用后,点击开启服务即可
开发者在登录SAE后,选中应用后,点击禁用服务即可,特别注意,禁用后会清除所有数据,请谨慎操作
KV DB的使用和MemcacheX的使用方式几乎一样,先init()后即可操作KV函数,示例:
$kv = new SaeKV();
// 初始化KV对象
$ret = $kv->init();
KV DB现支持以下操作:
get 按key读取
mget 按key批量读取
pkrge360百科t 按key前缀查找
set 更新
delete 删除
默认使用urle相量伟按陆ncode来编码key,之前采用其他编码方式以中文作为key的用户,可以通过SaeKV::get_options/S限首aeKV::set_optio缺矿银扩衣建火观谁ns来获取和设置是否编码key,以禁用key编码的方式来解育深飞过决无法get中文key的问题。
代码示例:
$flags = $kv->get_options();
$kv->set_options($flags & ~SaeKV::OPT_ENCODEKEY);
如何启用服务
应用使用KVD哥持厂B服务需要在应用的KVDB管理界面中开启服务,之后再代码中参照API接口文档调用即可。如果你需要关闭KVDB服务,在面板中点击禁用服务即可,你需径阶语口象座策矛赶林年要特别注意的是禁用后会清空KVDB中的所有数据,请谨慎操作。
本地环境使用
本地开发环境的KVDB服务采用JavaDB进行模拟,你仅需将derby已短形担杂际封燃军.jar(在下载中心可下载)放入工程的class皇终管呀促path中即可使用。另外由于本地环境只是模拟环境,所以效率达不到线上环境真实服务速度。
支持数阿织需三病形另青活冷据类型
KVDB支持boolean,long,double,byte[]四种基本类型直接存取操作,当然你也可以存取其他数据类型(short、float、int)或是对象(String和自定义对象等),但是你需要将数据类型做适当的转换。API中提供了SaeKVUtil工具类,可以帮你简化数据类型转换的操作,详情请看下文的使用范例。
使用范例
对KVDB所有操作都封装在SaeKV类中,当然存储对象等类型时你可以使用SaeKVUtil进行类型转换。在调用KVDB操作前你需要先初始化服务,即需先调用SaeKV的init()方法,需要注意的是你必须基于请求来执行初始化操作。
SaeKV kv=new SaeKV();
值冲医父至财杂酒 //初始化服务
kv.in室几政保买话院一例倍口it();
基本数据类型存存取
//存取现各婷军响提设long类型
kv.set("longValue", 6553鲁温盾巴神善田新江增它5L);
kv.get("longValue");
受极强死带大坚亲数树 //存取bool种附承依零千走ean类型
kv.set("boolean", true);
kv.get("boolean");
//存取double类型
kv.set("doubleValue",1.24);
kv.get("doubleValue");
//存取byte[]类型
kv.set("bytes",new byte[]{1,2});
byte [] b = kv.get("bytes");
//存取int类型(需转换成long)
kv.set("intValue", SaeKVUtil.intToLong(123));
SaeKVUtil.longToInt(kv.get("intValue"));
//存取float类型
kv.set("floatValue",1.24f);
kv.get("floatValue");
//存取short类型
kv.set("shortValue",(short)1);
SaeKVUtil.longToShort(kv.get("shortValue"))
String类型存取
存取String有两种方法,一种是使用SaeKVUtil的StringToByte方法将String转换成byte[]进行存储,再用SaeKVUtil的byteToString方法取出byte[]进行转换。第二种方法是将String看做是可序列化的对象,和普通对象一样存取。
//存取String类型 注意这里StringToByte返回的是String的getBytes()值,并非序列化后的byte[]
kv.set("string", SaeKVUtil.StringToByte("abc"));
SaeKVUtil.byteToString((byte[])kv.get("string"));
//第二种存储方式 把String当做可序列化对象来存储区
kv.set("string1", SaeKVUtil.serializable("abc"));
SaeKVUtil.deserializable((byte[])kv.get("string1"));
对象类型存取
这里需要特别注意的是,只有可序列化的对象(实现Serializable接口)才能存储到kvdb中
//存取对象类型 Person实现Serializable接口
kv.set("person", SaeKVUtil.serializable(new Person(1,"ward")));
SaeKVUtil.deserializable(kv.get("person"));
范围查找
范围查找是根据key的范围来查找对应的值,返回值类型为Map
/*
* startKey - 范围查找起始的key
* endKey - 范围查找结束的key
* isContainStartVlaue - 是否包含第一个查到的key
* isContainEndValue - 是否包含最后一个查到的key
* queryCount 查询的数量
*/
kv.rget("a","d",true,true,5)
//当然你也可以用简化的方法
kv.rget("a","d");
前缀查找
前缀查找可根据key值的前缀来过滤查找数据,返回值类型为Map
/**
* key前缀
* 查询数量,最多支持100个,如果超过100个只按100个查询
* 是否包含查找的值,如果设置此值为false,则返回的map中所有的value都为null
* 需要比较的key,如果存储的key为test1,test2,test3,test4,输入test2,则返回的test3和test4
*/
kv.pkrget("test",100,true,"test1");
//简化方法
kv.pkrget("test","test1");
查找多个key的值
可获取多个key值(String数组)的Value对应关系,返回值类型为Map
//key值数量必须小于32
kv.getMulti(new String[]{"test1","test2"});
范围删除
根据key值范围范围删除,和范围查找相视
/**
* startKey 起始的key
* endKey 结束的key
* isContainStartVlaue 是否包含第一个查到的key
* isContainEndValue 是否包含最后一个查到的key
* deleteCount 删除的数量
* @return 删除操作是否成功
*/
kv.rdel("a","d",true,true,3);
//同样也可以使用简便的方法
kv.rdel("a","d");
KVDB服务使用前需要在 管理面板 中启用,不再使用时可以在面板中禁用,禁用会删除所有数据。
class sae.kvdb.Error
通用错误
class sae.kvdb.RouterError
路由meta信息错误
class sae.kvdb.StatusError
kvdb状态不为OK
class sae.kvdb.KVClient(debug=0)
KVDB客户端基于python-memcached,大多数method使用方法相同。 如果不能成功创建KVClient,则抛出 sae.kvdb.Error 异常。
debug 是否输出详细调试、错误信息到日志,默认关闭
set(key, val, time=0, min_compress_len=0)
设置key的值为val,成功则返回True
time 该key的超时时间,请参阅memcached协议Storage 。
min_compress_len 启用zlib.compress压缩val的最小长度,如果val的长度大于此值 则启用压缩,0表示不压缩。
add(key, val, time=0, min_compress_len=0)
同set,但只在key不存在时起作用
replace(key, val, time=0, min_compress_len=0)
同set,但只在key存在时起作用
delete(key, time=0)
删除key,成功返回1,失败返回0。
time 为后续多少秒内set/update操作会失败。
get(key)
从kvdb中获取一个key的值。成功返回key的值,失败则返回None
get_multi(keys, key_prefix='')
从kvdb中一次获取多个key的值。返回一个key/value的dict。
keys: key的列表,类型必须为list。
key_prefix: 所有key的前缀。请求时会在所有的key前面加上该前缀,返回值里所有的key都会去掉该前缀。
get_by_prefix(prefix, max_count=100, start_key=None)
从kvdb中查找指定前缀的 key/value pair。返回一个list,该list中每个item为一个(key, value)的tuple。
prefix: 需要查找的key的前缀。
max_count: 最多返回的item个数,默认为100。
start_key: 指定返回的第一个item的key,该key不包含在返回中。
getkeys_by_prefix(prefix, max_count=100, start_key=None)
从kvdb中查找指定前缀的key。返回符合条件的key的list。
prefix: 需要查找的key的前缀。
max_count: 最多返回的key的个数,默认为100。
start_key: 指定返回的第一个key,该key不包含在返回中。
get_info()
获取本应用kvdb统计数据,返回一个字典:
{
'outbytes': 126,
'total_size': 3,
'inbytes': 180,
'set_count': 60,
'delete_count': 21,
'total_count': 1,
'get_count': 42
}
disconnect_all()
关闭kvdb连接
示例代码:
import sae.kvdb
kv = sae.kvdb.KVClient()
k = 'foo'
kv.set(k, 2)
kv.delete(k)
kv.add(k, 3)
kv.get(k)
kv.replace(k, 4)
kv.get(k)
print kv.get_info()
服务限制
存储空间:100G
最大记录条数:1,000,000,000
key的最大长度:200 Bytes
value的最大长度:4 M
get_multi获取的最大KEY个数:32