文件夹

1. 简单介绍

2. 安装步骤及问题小记

3. 部署配置

4. Javaclient測试

5. 參考资料

声明

1. 以下的安装部署基于Linux系统环境:centos 6(64位),其他Linux版本号可能有所差异。

2. 网上有人说tair安装失败可能是由于gcc版本号问题,高版本号的gcc可能不支持某些特性导致安装失败。经过实验证明。该说法是错误的,tair安装失败有各种可能的原因但绝对与gcc版本号无关,比方我的gcc開始版本号为4.4.7,后来tair安装失败,我又一次编译低版本号的gcc(gcc4.1.2)。可是问题相同出现。

后来发现是其他原因。修正后又一次用高版本号gcc4.4.7成功安装。

3. 以下的内容部分參考tair官方介绍文档,转载请注明原文地址。

正文

1. 简单介绍

tair 是淘宝自己开发的一个分布式 key/value 存储引擎. tair 分为持久化和非持久化两种使用方式. 非持久化的 tair 能够看成是一个分布式缓存. 持久化的 tair 将数据存放于磁盘中. 为了解决磁盘损坏导致数据丢失, tair 能够配置数据的备份数目, tair 自己主动将一份数据的不同备份放到不同的主机上, 当有主机发生异常, 无法正常提供服务的时候, 其余的备份会继续提供服务.

2. 安装步骤及问题小记

2.1 安装步骤

由于tair的实现用到了底层库 tbsys 和 tbnet,因此在安装tair之前须要先安装依赖库 tbsys 和 tbnet。

2.1.1 获取源代码

首先须要通过svn下载源代码,能够通过sudo yum install subversion安装svn服务。

  1. svn checkout http://code.taobao.org/svn/tb-common-utils/trunk/ tb-common-utils # 获取tbsys 和 tbnet的源代码
  2. svn checkout http://code.taobao.org/svn/tair/trunk/ tair # 获取tair源代码

2.1.2 安装依赖库或软件

编译tair或tbnet/tbsys之前须要预先安装一些编译所需的依赖库或软件。
在安装这些依赖之前最好首先检查系统是否已经安装,在用rpm管理软件包的os上能够使用rpm -q 软件包名查看是否已安装该软件或库。
a. 安装libtool
sudo yum install libtool # 同一时候会安装libtool所依赖的automake和autoconfig
b. 安装boost-devel库
sudo yum install boost-devel
c. 安装zlib库
sudo yum install zlib-devel

2.1.3 编译安装tbsys和tbnet

  1. tair 的底层依赖于tbsys库和tbnet库, 所以要先编译安装这两个库.
  2. a. 环境变量设置 TBLIB_ROOT
取得源代码后, 先指定环境变量 TBLIB_ROOT 为须要安装的文件夹. 这个环境变量在兴许 tair 的编译安装中仍旧会被使用到. 
比方要安装到当前用户的lib文件夹下, 则指定export TBLIB_ROOT="~/lib"。
b. 安装
进入源代码文件夹, 执行build.sh进行安装. 

  1. 2.1.4 编译安装tair

进入 tair 源代码文件夹,依次按以下顺序编译安装
./bootstrap.sh
./configure # 注意, 在执行configue的时候, 能够使用 --with-boost=xxxx 来指定boost的文件夹. 使用--with-release=yes 来编译release版本号.
make
make install
成功安装后会在当前用户home文件夹下生成文件夹tair_bin,即tair的成功安装后的文件夹。

2.2 问题小记

安装过程并非一帆风顺的,期间出现了非常多问题,在此简单记录以供參考。

2.2.1 g++未安装

checking for C++ compiler default output file name...
configure: error: in `/home/config_server/tair/tb-common-utils/tbnet':
configure: error: C++ compiler cannot create executables
See `config.log' for more details.
make: *** No targets specified and no makefile found. Stop.
make: *** No rule to make target `install'. Stop.

说明安装了gcc但未安装g++,而tair是用C++开发的,因此仅仅能用g++编译。通过过sudo yum install gcc-c++安装就可以。

2.2.2 头文件路径错误

In file included from channel.cpp:16:
tbnet.h:39:19: error: tbsys.h: No such file or directory
databuffer.h: In member function 'void tbnet::DataBuffer::expand(int)':
databuffer.h:429: error: 'ERROR' was not declared in this scope
databuffer.h:429: error: 'TBSYS_LOG' was not declared in this scope
socket.h: At global scope:
socket.h:191: error: 'tbsys' has not been declared
socket.h:191: error: ISO C++ forbids declaration of 'CThreadMutex' with no type
socket.h:191: error: expected ';' before '_dnsMutex'
channelpool.h:85: error: 'tbsys' has not been declared
channelpool.h:85: error: ISO C++ forbids declaration of 'CThreadMutex' with no type
channelpool.h:85: error: expected ';' before '_mutex'
channelpool.h:93: error: 'atomic_t' does not name a type
channelpool.h:94: error: 'atomic_t' does not name a type
connection.h:164: error: 'tbsys' has not been declared
connection.h:164: error: ISO C++ forbids declaration of 'CThreadCond' with no type
connection.h:164: error: expected ';' before '_outputCond'
iocomponent.h:184: error: 'atomic_t' does not name a type
iocomponent.h: In member function 'int tbnet::IOComponent::addRef()':
iocomponent.h:108: error: '_refcount' was not declared in this scope
iocomponent.h:108: error: 'atomic_add_return' was not declared in this scope
iocomponent.h: In member function 'void tbnet::IOComponent::subRef()':
iocomponent.h:115: error: '_refcount' was not declared in this scope
iocomponent.h:115: error: 'atomic_dec' was not declared in this scope
iocomponent.h: In member function 'int tbnet::IOComponent::getRef()':
iocomponent.h:122: error: '_refcount' was not declared in this scope
iocomponent.h:122: error: 'atomic_read' was not declared in this scope
transport.h: At global scope:
transport.h:23: error: 'tbsys' has not been declared
transport.h:23: error: expected `{' before 'Runnable'
transport.h:23: error: invalid function declaration
packetqueuethread.h:28: error: 'tbsys' has not been declared
packetqueuethread.h:28: error: expected `{' before 'CDefaultRunnable'
packetqueuethread.h:28: error: invalid function declaration
connectionmanager.h:93: error: 'tbsys' has not been declared
connectionmanager.h:93: error: ISO C++ forbids declaration of 'CThreadMutex' with no type
connectionmanager.h:93: error: expected ';' before '_mutex'
make[1]: *** [channel.lo] Error 1
make[1]: Leaving directory `/home/tair/tair/tb-common-utils/tbnet/src'
make: *** [install-recursive] Error 1
have installed in ~/lib

由于tbnet和tbsys在两个不同的文件夹,但它们的源代码文件中头文件的互相引用却没有加绝对或相对路径,将两个文件夹的源代码加入到C++环境变量中就可以。

CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/home/tair/tair/tb-common-utils/tbsys/src:/home/tair/tair/tb-common-utils/tbnet/src
export CPLUS_INCLUDE_PATH

3. 部署配置

tair的执行, 至少须要一个 config server 和一个 data server. 推荐使用两个 config server 多个data server的方式. 两个config server有主备之分.
tair有三个配置文件。各自是对config server、data server及group信息的配置,在tair_bin安装文件夹下的etc文件夹下有这三个配置文件的样例,我们将其复制一下,成为我们须要的配置文件。

cp configserver.conf.default configserver.conf
cp dataserver.conf.default dataserver.conf
cp group.conf.default group.conf

我的部署环境:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFueHVlemFpcGlhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

在配置之前。请查阅官网给出的配置文件字段详细解释,以下直接贴出我自己的配置并加以简单的说明。

3.1 配置config server

#
# tair 2.3 --- configserver config
# [public]
config_server=10.10.7.144:51980
config_server=10.10.7.144:51980 [configserver]
port=51980
log_file=/home/dataserver1/tair_bin/logs/config.log
pid_file=/home/dataserver1/tair_bin/logs/config.pid
log_level=warn
group_file=/home/dataserver1/tair_bin/etc/group.conf
data_dir=/home/dataserver1/tair_bin/data/data
dev_name=venet0:0

注意事项:

(1)首先须要配置config server的服务器地址和端口号,端口号能够默认,服务器地址改成自己的,有一主一备两台configserver,这里仅为測试使用就设置为一台了。

(2)log_file/pid_file等的路径设置最好用绝对路径,默认的是相对路径,并且是不对的相对路径(没有返回上级文件夹)。因此这里须要改动。注意data文件和log文件非常重要,data文件必不可少。而log文件是部署出错后能给你详细的出错原因。

(3)dev_name非常重要。须要设置为你自己当前网络接口的名称,默觉得eth0。这里我依据自己的网络情况进行了改动(ifconfig查看网络接口名称)。

3.2 配置data server

#
#  tair 2.3 --- tairserver config 
#
[public]
config_server=10.10.7.144:51980
config_server=10.10.7.144:51980 [tairserver]
#
#storage_engine:
#
# mdb 
# kdb
# ldb
#
storage_engine=ldb
local_mode=0
#
#mdb_type:
# mdb
# mdb_shm
#
mdb_type=mdb_shm #
# if you just run 1 tairserver on a computer, you may ignore this option.
# if you want to run more than 1 tairserver on a computer, each tairserver must have their own "mdb_shm_path"
#
#
mdb_shm_path=/mdb_shm_path01
#tairserver listen port
port=51910
heartbeat_port=55910 process_thread_num=16
#
#mdb size in MB
#
slab_mem_size=1024
log_file=/home/dataserver1/tair_bin/logs/server.log
pid_file=/home/dataserver1/tair_bin/logs/server.pid
log_level=warn
dev_name=venet0:0
ulog_dir=/home/dataserver1/tair_bin/data/ulog
ulog_file_number=3
ulog_file_size=64
check_expired_hour_range=2-4
check_slab_hour_range=5-7
dup_sync=1 do_rsync=0
# much resemble json format
# one local cluster config and one or multi remote cluster config.
# {local:[master_cs_addr,slave_cs_addr,group_name,timeout_ms,queue_limit],remote:[...],remote:[...]}
rsync_conf={local:[10.0.0.1:5198,10.0.0.2:5198,group_local,2000,1000],remote:[10.0.1.1:5198,10.0.1.2:5198,group_remote,2000,3000]}
# if same data can be updated in local and remote cluster, then we need care modify time to
# reserve latest update when do rsync to each other.
rsync_mtime_care=0
# rsync data directory(retry_log/fail_log..)
rsync_data_dir=/home/dataserver1/tair_bin/data/remote
# max log file size to record failed rsync data, rotate to a new file when over the limit
rsync_fail_log_size=30000000
# whether do retry when rsync failed at first time
rsync_do_retry=0
# when doing retry,  size limit of retry log's memory use
rsync_retry_log_mem_size=100000000 [fdb]
# in MB
index_mmap_size=30
cache_size=256
bucket_size=10223
free_block_pool_size=8
data_dir=/home/dataserver1/tair_bin/data/fdb
fdb_name=tair_fdb [kdb]
# in byte
map_size=10485760      # the size of the internal memory-mapped region
bucket_size=1048583    # the number of buckets of the hash table
record_align=128       # the power of the alignment of record size
data_dir=/home/dataserver1/tair_bin/data/kdb      # the directory of kdb's data [ldb]
#### ldb manager config
## data dir prefix, db path will be data/ldbxx, "xx" means db instance index.
## so if ldb_db_instance_count = 2, then leveldb will init in
## /data/ldb1/ldb/, /data/ldb2/ldb/. We can mount each disk to
## data/ldb1, data/ldb2, so we can init each instance on each disk.
data_dir=/home/dataserver1/tair_bin/data/ldb
## leveldb instance count, buckets will be well-distributed to instances
ldb_db_instance_count=1
## whether load backup version when startup.
## backup version may be created to maintain some db data of specifid version.
ldb_load_backup_version=0
## whether support version strategy.
## if yes, put will do get operation to update existed items's meta info(version .etc),
## get unexist item is expensive for leveldb. set 0 to disable if nobody even care version stuff.
ldb_db_version_care=1
## time range to compact for gc, 1-1 means do no compaction at all
ldb_compact_gc_range = 3-6
## backgroud task check compact interval (s)
ldb_check_compact_interval = 120
## use cache count, 0 means NOT use cache,`ldb_use_cache_count should NOT be larger
## than `ldb_db_instance_count, and better to be a factor of `ldb_db_instance_count.
## each cache mdb's config depends on mdb's config item(mdb_type, slab_mem_size, etc)
ldb_use_cache_count=1
## cache stat can't report configserver, record stat locally, stat file size.
## file will be rotate when file size is over this.
ldb_cache_stat_file_size=20971520
## migrate item batch size one time (1M)
ldb_migrate_batch_size = 3145728
## migrate item batch count.
## real batch migrate items depends on the smaller size/count
ldb_migrate_batch_count = 5000
## comparator_type bitcmp by default
# ldb_comparator_type=numeric
## numeric comparator: special compare method for user_key sorting in order to reducing compact
## parameters for numeric compare. format: [meta][prefix][delimiter][number][suffix] 
## skip meta size in compare
# ldb_userkey_skip_meta_size=2
## delimiter between prefix and number 
# ldb_userkey_num_delimiter=:
####
## use blommfilter
ldb_use_bloomfilter=1
## use mmap to speed up random acess file(sstable),may cost much memory
ldb_use_mmap_random_access=0
## how many highest levels to limit compaction
ldb_limit_compact_level_count=0
## limit compaction ratio: allow doing one compaction every ldb_limit_compact_interval
## 0 means limit all compaction
ldb_limit_compact_count_interval=0
## limit compaction time interval
## 0 means limit all compaction
ldb_limit_compact_time_interval=0
## limit compaction time range, start == end means doing limit the whole day.
ldb_limit_compact_time_range=6-1
## limit delete obsolete files when finishing one compaction
ldb_limit_delete_obsolete_file_interval=5
## whether trigger compaction by seek
ldb_do_seek_compaction=0
## whether split mmt when compaction with user-define logic(bucket range, eg) 
ldb_do_split_mmt_compaction=0 #### following config effects on FastDump ####
## when ldb_db_instance_count > 1, bucket will be sharded to instance base on config strategy.
## current supported:
##  hash : just do integer hash to bucket number then module to instance, instance's balance may be
##         not perfect in small buckets set. same bucket will be sharded to same instance
##         all the time, so data will be reused even if buckets owned by server changed(maybe cluster has changed),
##  map  : handle to get better balance among all instances. same bucket may be sharded to different instance based
##         on different buckets set(data will be migrated among instances).
ldb_bucket_index_to_instance_strategy=map
## bucket index can be updated. this is useful if the cluster wouldn't change once started
## even server down/up accidently.
ldb_bucket_index_can_update=1
## strategy map will save bucket index statistics into file, this is the file's directory
ldb_bucket_index_file_dir=/home/dataserver1/tair_bin/data/bindex
## memory usage for memtable sharded by bucket when batch-put(especially for FastDump)
ldb_max_mem_usage_for_memtable=3221225472
#### #### leveldb config (Warning: you should know what you're doing.)
## one leveldb instance max open files(actually table_cache_ capacity, consider as working set, see `ldb_table_cache_size)
ldb_max_open_files=655
## whether return fail when occure fail when init/load db, and
## if true, read data when compactiong will verify checksum
ldb_paranoid_check=0
## memtable size
ldb_write_buffer_size=67108864
## sstable size
ldb_target_file_size=8388608
## max file size in each level. level-n (n > 0): (n - 1) * 10 * ldb_base_level_size
ldb_base_level_size=134217728
## sstable's block size
# ldb_block_size=4096
## sstable cache size (override `ldb_max_open_files)
ldb_table_cache_size=1073741824
##block cache size
ldb_block_cache_size=16777216
## arena used by memtable, arena block size
#ldb_arenablock_size=4096
## key is prefix-compressed period in block,
## this is period length(how many keys will be prefix-compressed period)
# ldb_block_restart_interval=16
## specifid compression method (snappy only now)
# ldb_compression=1
## compact when sstables count in level-0 is over this trigger
ldb_l0_compaction_trigger=1
## write will slow down when sstables count in level-0 is over this trigger
## or sstables' filesize in level-0 is over trigger * ldb_write_buffer_size if ldb_l0_limit_write_with_count=0
ldb_l0_slowdown_write_trigger=32
## write will stop(wait until trigger down)
ldb_l0_stop_write_trigger=64
## when write memtable, max level to below maybe
ldb_max_memcompact_level=3
## read verify checksum
ldb_read_verify_checksums=0
## write sync log. (one write will sync log once, expensive)
ldb_write_sync=0
## bits per key when use bloom filter
#ldb_bloomfilter_bits_per_key=10
## filter data base logarithm. filterbasesize=1<<ldb_filter_base_logarithm
#ldb_filter_base_logarithm=12                                  

该配置文件内容非常多,红色标出来的是我改动的部分。其他的採用默认。当中:

(1)config_server的配置与之前必须全然相同。

(2)这里面的port和heartbeat_port是data server的端口号和心跳端口号,必须确保系统能给你使用这些端口号。一般默认的就可以。这里我改动是由于自己的Linux系统仅仅同意分配30000以后的端口号。依据自己情况改动。

(3)data文件、log文件等非常重要,与前一样,最好用绝对路径

3.3 配置group信息

#group name
[group_1]
# data move is 1 means when some data serve down, the migrating will be start. 
# default value is 0
_data_move=0
#_min_data_server_count: when data servers left in a group less than this value, config server will stop serve for this group
#default value is copy count.
_min_data_server_count=1
#_plugIns_list=libStaticPlugIn.so
_build_strategy=1 #1 normal 2 rack 
_build_diff_ratio=0.6 #how much difference is allowd between different rack 
# diff_ratio =  |data_sever_count_in_rack1 - data_server_count_in_rack2| / max (data_sever_count_in_rack1, data_server_count_in_rack2)
# diff_ration must less than _build_diff_ratio
_pos_mask=65535  # 65535 is 0xffff  this will be used to gernerate rack info. 64 bit serverId & _pos_mask is the rack info, 
_copy_count=1    
_bucket_number=1023
# accept ds strategy. 1 means accept ds automatically
_accept_strategy=1 # data center A
_server_list=10.10.7.146:51910
#_server_list=192.168.1.2:5191
#_server_list=192.168.1.3:5191
#_server_list=192.168.1.4:5191 # data center B
#_server_list=192.168.2.1:5191
#_server_list=192.168.2.2:5191
#_server_list=192.168.2.3:5191
#_server_list=192.168.2.4:5191 #quota info
_areaCapacity_list=0,1124000;

这个文件我仅仅配置了data server列表,我仅仅有一个dataserver,因此仅仅需配置一个。

3.4 启动集群

在完毕安装配置之后, 能够启动集群了.  启动的时候须要先启动data server 然后再启动cofnig server.  假设是为已有的集群加入dataserver则能够先启动dataserver进程然后再改动gruop.conf,假设你先改动group.conf再启动进程,那么须要执行touch group.conf;在scripts文件夹下有一个脚本 tair.sh 能够用来帮助启动 tair.sh start_ds 用来启动data server.  tair.sh start_cs 用来启动config server.  这个脚本比較简单, 它要求配置文件放在固定位置, 採用固定名称.  使用者能够通过执行安装文件夹下的bin下的 tair_server (data server) 和 tair_cfg_svr(config server) 来启动集群.

进入tair_bin文件夹后,按顺序启动:

sudo sbin/tair_server -f etc/dataserver.conf     # 在dataserver端启动
sudo sbin/tair_cfg_svr -f etc/configserver.conf # 在config server端启动

执行启动命令后,在两端通过ps aux | grep tair查看是否启动了。这里启动起来仅仅是第一步,还须要測试看是否真的启动成功。通过以下命令測试:

sudo sbin/tairclient -c 10.10.7.144:51980 -g group_1
TAIR> put k1 v1       
put: success
TAIR> put k2 v2
put: success
TAIR> get k2
KEY: k2, LEN: 2

当中10.10.7.144:51980是config server IP:PORT,group_1是group name,在group.conf里配置的。

3.4 部署过程中的错误记录

假设启动不成功或測试put/get时出现故障,那么须要查看config server端的logs/config.log和data server端的logs/server.log日志文件,里面会有详细的报错信息。

3.4.1  Too many open files

[2014-07-09 10:37:24.863119] ERROR start (stat_manager.cpp:30) [139767832377088] open file [/home/dataserver1/tair_bin/data/ldb1/ldb/tair_db_001013.stat] failed: Too many open files
[2014-07-09 10:37:24.863132] ERROR start (stat_manager.cpp:30) [139767832377088] open file [/home/dataserver1/tair_bin/data/ldb1/ldb/tair_db_001014.stat] failed: Too many open files
[2014-07-09 10:37:24.863145] ERROR start (stat_manager.cpp:30) [139767832377088] open file [/home/dataserver1/tair_bin/data/ldb1/ldb/tair_db_001015.stat] failed: Too many open files
[2014-07-09 10:37:24.863154] ERROR start (stat_manager.cpp:30) [139767832377088] open file [/home/dataserver1/tair_bin/data/ldb1/ldb/tair_db_001016.stat] failed: Too many open files
[2014-07-09 10:37:24.863162] ERROR start (stat_manager.cpp:30) [139767832377088] open file [/home/dataserver1/tair_bin/data/ldb1/ldb/tair_db_001017.stat] failed: Too many open files

由于我的存储引擎选择的是ldb,而ldb有一个配置ldb_max_open_files=65535,即默认最多能打开的文件个数是65535个,可是我的系统不同意,能够通过“ulimit -n”查看系统执行程序中打开的最多文件个数。一般为1024个,远远小于65535,这时有两个办法来解决,一是改动ldb_max_open_files的值,使其小于1024。二是改动系统最多同意打开文件个数(以下的參考资料有提供改动的方法),由于我是測试使用,因此这里直接改动了ldb_max_open_files的值。

3.4.2 data server问题

dataserver没配置好会报各种错误,以下列举一些我遇到的错误:

问题1:

TAIR> put abc a 
put: unknow 
TAIR> put a 11 
put: unknow 
TAIR> put abc 33 
put: unknow 
TAIR> get a 
get failed: data not exists.

问题2:

ERROR wakeup_wait_object (../../src/common/wait_object.hpp:302) [140627106383616] [3] packet is null

这些都是dataserver開始启动起来了。可是使用put/get时报错。然后dataserver立即down掉的情况,这时候就要依据log查看详细报错信息。改动错误的配置。

还有以下这种报错信息:

[2014-07-09 09:08:11.646430] ERROR rebuild (group_info.cpp:879) [139740048353024] can not get enough data servers. need 1 lef 0

这是config server在启动时找不到data server。也就是data server必须要先启动成功后才干启动config server。

3.4.3 端口问题

start tair_cfg_srv listen port 5199 error

有时候使用默认的端口号也不一定行。须要依据系统限制进行设置,比方我的系统环境仅仅能执行普通用户使用30000以上的端口号。因此这里我就不能使用默认端口号了,改下就可以。

4. Javaclient測试

Tair是一个分布式的key/value存储系统。数据往往存储在多个数据节点上。

client须要决定数据存储的详细节点,然后才干完毕详细的操作。

Tair的client通过和configserver交互获取这部分信息。configserver会维护一张表,这张表包括hash值与存储其对应数据的节点的对比关系。

client在启动时,须要先和configserver通信,获取这张对比表。

在获取到对比表后,client便能够開始提供服务。client会依据请求的key的hash值,查找对比表中负责该数据的数据节点,然后通过和数据节点通信完毕用户的请求。

Tair当前支持Java和c++语言的client。Javaclient已有对应的实现(可从这里下载到对应的jar包),我们直接使用封装的接口操作就可以,但C++client眼下还没看到实现版本号(须要自己实现)。

这里以简单的Javaclient为例进行client測试。

4.1 依赖jar包

Java測试程序除了须要封装好的tair相关jar包之外,还须要tair依赖的一些jar包,详细的有以下几个(不一定是这个版本号号):

commons-logging-1.1.3.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.7.jar
log4j-1.2.17.jar
mina-core-1.1.7.jar
tair-client-2.3.1.jar

4.2 Javaclient程序

首先请參考Tair用户指南里面的关于javaclient的接口说明,以下直接给出演示样例,非常easy理解。

package tair.client;

import java.util.ArrayList;
import java.util.List; import com.taobao.tair.DataEntry;
import com.taobao.tair.Result;
import com.taobao.tair.ResultCode;
import com.taobao.tair.impl.DefaultTairManager; /**
* @author WangJianmin
* @date 2014-7-9
* @description Java-client test application for tair.
*
*/
public class TairClientTest { public static void main(String[] args) { // 创建config server列表
List<String> confServers = new ArrayList<String>();
confServers.add("10.10.7.144:51980");
// confServers.add("10.10.7.144:51980"); // 可选 // 创建client实例
DefaultTairManager tairManager = new DefaultTairManager();
tairManager.setConfigServerList(confServers); // 设置组名
tairManager.setGroupName("group_1");
// 初始化client
tairManager.init(); // put 10 items
for (int i = 0; i < 10; i++) {
// 第一个參数是namespace,第二个是key,第三是value,第四个是版本号。第五个是有效时间
ResultCode result = tairManager.put(0, "k" + i, "v" + i, 0, 10);
System.out.println("put k" + i + ":" + result.isSuccess());
if (!result.isSuccess())
break;
} // get one
// 第一个參数是namespce。第二个是key
Result<DataEntry> result = tairManager.get(0, "k3");
System.out.println("get:" + result.isSuccess());
if (result.isSuccess()) {
DataEntry entry = result.getValue();
if (entry != null) {
// 数据存在
System.out.println("value is " + entry.getValue().toString());
} else {
// 数据不存在
System.out.println("this key doesn't exist.");
}
} else {
// 异常处理
System.out.println(result.getRc().getMessage());
} } }

执行结果:

log4j:WARN No appenders could be found for logger (com.taobao.tair.impl.ConfigServer).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
put k0:true
put k1:true
put k2:true
put k3:true
put k4:true
put k5:true
put k6:true
put k7:true
put k8:true
put k9:true
get:true
value is v3

注意事项:測试假设不是在config server或data server上进行,那么一定要确保測试端系统与config server和data server能互相通信,即ping通。否则有可能会报以下这种错误:

Exception in thread "main" java.lang.RuntimeException: init config failed
 at com.taobao.tair.impl.DefaultTairManager.init(DefaultTairManager.java:80)
 at tair.client.TairClientTest.main(TairClientTest.java:27)

我已将演示样例程序、须要的jar包及Makefile文件(我在Linux系统下測试,未用Eclipse跑程序)打包,须要的能够从这里下载。

5. 參考资料

1. TAIR home page

2. Tair用户指南

3. Too many open files 问题的解决

淘宝分布式 key/value 存储引擎Tair安装部署过程及Javaclient測试一例的更多相关文章

  1. 淘宝开源Key/Value结构数据存储系统Tair技术剖析

    摘要: Tair的功能 Tair是一个Key/Value结构数据的解决方案,它默认支持基于内存和文件的两种存储方式,分别和我们通常所说的缓存和持久化存储对应. Tair除了普通Key/Value系统提 ...

  2. Tair分布式key/value存储

    [http://www.lvtao.net/database/tair.html](特别详细)   tair 是淘宝自己开发的一个分布式 key/value 存储引擎. tair 分为持久化和非持久化 ...

  3. 淘宝分布式NOSQL框架:Tair

    Tair 分布式K-V存储方案 tair 是淘宝的一个开源项目,它是一个分布式的key/value结构数据的解决方案. 作为一个分布式系统,Tair由一个中心控制节点(config server)和一 ...

  4. 【Tair】淘宝分布式NOSQL框架:Tair

    Tair是淘宝的一个开源项目,它是一个分布式的key/value结构数据的解决方案. 一.基本组成 作为一个分布式系统,Tair由一个中心控制节点(config server)和一系列的服务节点(da ...

  5. 基于淘宝开源Tair分布式KV存储引擎的整合部署

    一.前言 Tair支撑了淘宝几乎所有系统的缓存信息(Tair = Taobao Pair,Pair即Key-Value键值对),内置了三个存储引擎:mdb(默认,类似于Memcache).rdb(类似 ...

  6. 淘宝分布式文件存储系统:TFS

    TFS ——分布式文件存储系统 TFS(Taobao File System)是淘宝针对海量非结构化数据存储设计的分布式系统,构筑在普通的Linux机器集群上,可为外部提供高可靠和高并发的存储访问. ...

  7. 淘宝分布式配置管理服务Diamond

    转载:http://blog.csdn.net/kevinlynx/article/details/40017109 在一个分布式环境中,同类型的服务往往会部署很多实例.这些实例使用了一些配置,为了更 ...

  8. Window平台搭建Redis分布式缓存集群 (一)server搭建及性能測试

    百度定义:Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对很多其它.包含string(字符串).list(链表).set(集合).zset(sort ...

  9. 对象存储服务MinIO安装部署分布式及Spring Boot项目实现文件上传下载

    目录 一.MinIO快速入门 1. MinIO简介 2. CentOS7更换成阿里云镜像 3. 安装 3.1 下载 3.2 运行测试 4. 配置脚本执行文件 4.1 创建配置执行文件 4.2 执行 二 ...

随机推荐

  1. OS X 10.10 Yosemite Beta能够下载了

    刚刚启动迅雷.蹦出一消息.点击后出现-- watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmlzdGE5OTk5OQ==/font/5a6L5L2T/fon ...

  2. GNOME界面简单使用

    GNOME界面 CentOS下的文件夹打开方式,默认是打开一个文件夹就重新的打开一个窗口,并不是在原有的文件夹中显示要打开文件夹的内容. 怎么修改: 打开任意一个文件夹. Edit --> pr ...

  3. MySqlClient访问tinyint字段返回布尔值

    原文 MySqlClient访问tinyint字段返回布尔值 症状: 使用MySqlClient访问tinyint       unsign 字段返回布尔值 true 和        false,但 ...

  4. android在其他线程中访问UI线程的方法

    1.Activity.runOnUiThread( Runnable ) 2.View.post( Runnable ) 3.View.postDelayed( Runnable, long ) 4. ...

  5. c++ char_traits模板类的实现!!!

    本人写过与此相关的两篇博客,一个是<cstring>头文件的实现,还有一个是<cwchar>的实现.这里的char_traits模板类在此基础上实现. 为了方便.将源码一起封装 ...

  6. 静态书架和js模拟翻书效果

    书籍图片随便找了个,有点难看,须要的自己替换个好看点的png格式图片 源代码下载:http://download.csdn.net/detail/sweetsuzyhyf/7604091

  7. Swift - 生成各种控件的工厂类(包含标签,按钮,输入框等)

    在iOS开发中,页面里有时会大量的用到一些控件,如果要一个个单独创建再设置样式的话就显得很麻烦.我们可以创建一个生成各种控件的工厂类,这样在需要的时候调用下就可以了. 下面以一个自定义的工厂类为例,其 ...

  8. u-boot的nand驱动写过程分析

    从命令说起,在u-boot输入下列命令: nand write 40008000 0 20000 命令的意思是将内存0x40008000开始的部分写入nand,从nand地址0开始写,写入长度是0x2 ...

  9. iotop 分析系统那些进程占用io资源

    iotop -b -o  -t  -qqq >> /tmp/iotop.log 1.直接yum安装,rh6的光盘里有包. yum install iotop   2.命令参数介绍   -o ...

  10. 为什么EXE文件出现了不该出现的“盾牌”

    下载了一个小程序,它的功能并不需要管理员权限.但是在Win7下面它的图标上出现了一个“小盾牌”,这意味着运行它需要提升权限……果然,双击时弹出了UAC对话框.用二进制编辑器打开这个EXE,发现它没有内 ...