Tair介绍

Tair(Taobao Pair)是淘宝开发的分布式Key-Value存储引擎
服务器端自动负载均衡
分为持久化和非持久化两种方式存储
非持久化:分布式缓存使用 Memcached(mdb)、Redis(rdb)
持久化:SQL-DB使用FireBird(fdb)
NoSQL-DB:使用Kyoto Cabinet(kdb)、LevelDB(ldb)
Tair采用可插拔存储引擎设计,以上这些存储引擎可以很方便的替换,还可以引入新的存储引擎比如:
MySQL

使用场景

分布式缓存
大多数使用场景
大访问少量临时数据的存储(kb左右)
用于缓存,降低对后端数据库的访问压力
session场景
高速访问某些数据结构的应用和计算(rdb)
数据源存储
快速读取数据(fdb)
持续大数据量的存入读取(ldb),交易快照
高频度的更新读取(ldb),库存

Tair整体架构分析

一个Tair集群主要包括client、Config server和Dataserver 三个不同的应用。
Client在初始化时,从Config server处获取数据的分布信息,根据分布信息和相应的Data server交互完
成用户的请求。
Config Server通过和Data Server的心跳(HeartBeat)维护集群中可用的节点,并根据可用的节点,
构建数据的在集群中的分布信息
Data server负责数据的存储,并按照Config server的指示完成数据的复制和迁移工作。

Config Server

Config Server是单点,采用一主一备的方式保证可靠性。
管理所有的data server, 维护data server的状态信息
用户配置的桶数量、副本数、机房信息
数据分布的对照表
协调数据迁移、管理进度,将数据迁移到负载较小的节点上
Client和ConfigServer的交互主要是为了获取数据分布的对照表,当client获取到对照表后,会cache这
张表,然后通过查这张表决定数据存储的节点,所以不需要和configserver交互,这使得Tair对外的服
务不依赖configserver,所以它不是传统意义上的中心节点
Config server维护的对照表有版本概念,由于集群变动或管理触发,构建新的对照表后,对照表的版本
号递增,并通过Data server的心跳,将新表同步给数据节点。
客户端和Data server交互时,Dataserver每次都把自己缓存的对照表版本号放入response结构中,返
回给客户端,客户端将Data server的对照表版本号和自己缓存的对照表版本号比较,如果不相同,会
主动和Config server通信,请求新的对照表。
Tair的Configserver使客户端使用时候,不需要配置数据节点列表,也不需要处理节点的的状态变化,
这使得Tair对最终用户来说使用和配置都很简单。

Data Server

Data server负责数据的物理存储,并根据Configserver构建的对照表完成数据的复制和迁移工作。
Data server具备抽象的存储引擎层,可以很方便地添加新存储引擎。Data server还有一个插件容器,
可以动态地加载/卸载插件。

Tair的存储引擎有一个抽象层,只要满足存储引擎需要的接口,便可以很方便地替换Tair底层的存储引
擎。比如你可以很方便地将bdb、tc甚至MySQL作为Tair的存储引擎,而同时使用Tair的分布方式、同步
等特性。
Tair默认包含两个存储引擎:mdb和fdb。
mdb是一个高效的缓存存储引擎,它有着和memcached类似的内存管理方式。mdb支持使用share
memory(tmpfs),这使得我们在重启Tair数据节点的进程时不会导致数据的丢失,从而使升级对应
用来说更平滑,不会导致命中率的较大波动。
fdb是一个简单高效的持久化存储引擎,使用树的方式根据数据key的hash值索引数据,加快查找速
度。索引文件和数据文件分离,尽量保持索引文件在内存中,以便减小IO开销。使用空闲空间池管理被
删除的空间。

Tair的安装与使用

环境准备

GIt

yum install git
yum update -y nss curl libcurl

svn

yum install subversion

Libtool

yum install libtool

boost-devel

yum install boost-devel

zlib

yum install zlib-devel

C++

yum install gcc-c++

项目源码下载和编译

tbsys库和tbnet库下载(tair底层依赖tbsys库和tbnet库)

#git源码下载
git clone https://github.com/kayaklee/tb-common-util.git
#设置环境变量
mkdir /var/tblib
export TBLIB_ROOT="/var/tblib"
#因为tbnet和tbsys在两个不同的目录,但它们的源码文件里头文件的互相引用却没有加绝对或相对路径,
将两个目录的源码加入到C++环境变量中即可。否则编译时会出现:“fatal error:tysys.h: No such
file or directory”的错误。
CPLUS_INCLUDE_PATH=/home/tair/tb-common-util/tbsys/src:/home/tair/tb-commonutil/
tbnet/src
export CPLUS_INCLUDE_PATH
#修改tbsys代码
cd ~/tb-common-util/trunk/tbsys/src
下载的代码有个错误:具体是tbsys/src/tblog.cpp中323行代码:需要将CLogger::CLogger&
CLogger::getLogger()改为CLogger& CLogger::getLogger()
#编译tbsys和tbnet
cd tb-common-utils
./build.sh
注:安装成功后,TBLIB_ROOT所指示的目录下会有include和lib两个目录。
tair下载
#git源码下载
git clone https://github.com/alibaba/tair.git
#安装依赖
yum install -y openssl-devel libcurl-devel
#编译
./bootstrap.sh
#检测和生成 Makefile
./configure
#编译和安装到目标目录
make -j
make install
注:默认安装位置是 ~/tair_bin
Tair配置和启动

下面以MDB引擎为例配置一个最小化的Tair集群(1 * ConfigServer + 1 * DataServer)

#查看和设置系统tmpfs
#MDB 引擎默认使用共享内存,所以需要查看并设置系统的tmpfs的大小
# 这里根据实际机器内存情况配置,必须大于Tair使用内存的配置
vim /etc/fstab
tmpfs /dev/shm tmpfs defaults,size=1024M 0 0
#生效
mount -o remount /dev/shm
#查看tmpfs
cat /etc/fstab | grep /dev/shm
显示tmpfs /dev/shm tmpfs rw,size=1G 0 0
# 定义配置文件 复制配置文件
cp etc/configserver.conf.default etc/configserver.conf
cp etc/group.conf.default etc/group.conf
etc/dataserver.conf.default etc/dataserver.conf
# configserver.conf
[public]
config_server=192.168.127.133:5198
#config_server=192.168.1.2:5198
#config_server=10.211.55.9:5198
#config_server=192.168.1.2:5198
dev_name=eno16777736
#group.conf
# data center A
_server_list=192.168.127.133:5191
#_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
#dataserver.conf
[public]
config_server=192.168.127.133:5198
#config_server=192.168.1.2:5198
dev_name=eno16777736
mdb_inst_shift=0
process_thread_num=4
io_thread_num=4
#这里 slab_mem_size控制MDB内存池的总大小,mdb_inst_shift 控制实例的个数,注意这里一个实例
必须大于512MB且小于64GB。
slab_mem_size=512
#修改 tair.sh启动脚本
#在CentOS 7下,安装目录下的 tair.sh 启动脚本有一行代码需要修改
tmpfs_size=`df -m |grep /dev/shm | awk '{print $2}'`
#启动Tair实例
#启动dataserver
tair_bin $ ./tair.sh start_ds
#启动configserver
tair_bin $ ./tair.sh start_cs
#查看进程
ps -ef |grep tair
注:执行后没有两行记录显示,说明启动失败,可查看logs中的log查看错误信息。
Tair测试
#客户端读写测试
tair_bin $ ./sbin/tairclient -c 192.168.127.133:5198 -g group_1
TAIR> health
TAIR> put key value
TAIR> get key
TAIR> remove key
TAIR> get key
Tair停止
#停止dataserver
tair_bin $ ./tair.sh stop_ds
#停止configserver
tair_bin $ ./tair.sh stop_cs

Tair高可用和负载均衡

Tair的高可用和负载均衡,主要通过对照表和数据迁移两大功能进行支撑。
对照表将数据分为若干个桶,并根据机器数量、机器位置进行负载均衡和副本放置,确保数据分布均
匀,并且在多机房有数据副本。
在集群发生变化时,会重新计算对照表,并进行数据迁移。

对照表

在Tair系统中,采用对照表将数据均衡的分布在DataServer上
还能动态适应节点的扩容和缩容
Tair基于一致性Hash算法存储数据,根据配置建立固定数量的桶(bucket)
桶为Hash环节点,hash(key) 顺时针 设置桶
桶是负载均衡和数据迁移的基本单位
config server 根据一定的策略把每个桶指派到不同的data server上,
因为数据按照key做hash算法,所以可以认为每个桶中的数据基本是平衡的,
保证了桶分布的均衡性, 就保证了数据分布的均衡性。
比如:

    bucket       data server0       192.168.127.132 192.168.127.1341       192.168.127.133 192.168.127.1352       192.168.127.132 192.168.127.1343       192.168.127.133 192.168.127.1354       192.168.127.132 192.168.127.1345       192.168.127.133 192.168.127.135

Tair支持自定义的备份数,比如你可以设置数据备份为2,以提高数据的可靠性。对照表可以很方便地支
持这个特性。
第二列为主节点的信息,第三列为辅节点信息。在Tair中,客户端的读写请求都是和主节点交互。
当有节点不可用时,如果是辅节点,那么configserver会重新为其指定一个辅节点,如果是持久化存
储,还将复制数据到新的辅节点上。如果是主节点,那么configserver首先将辅节点提升为主节点,对
外提供服务,并指定一个新的辅节点,确保数据的备份数。

对照表的初始化

第一次启动ConfigServer会根据在线的DataServer生成对照表
ConfigServer会启动一个线程(table_builder_thread),该线程会每秒检查一次是否需要重新构造对照

Tair 提供了两种生成对照表的策略:

负载均衡优先

config server会尽量的把桶均匀的分布到各个data server上
一个桶的备份数据不能在同一台主机上

位置安全优先

一般我们通过控制 _pos_mask(Tair的一个配置项) 来使得不同的机房具有不同的位置信息
一个桶的备份数据不能都位于相同的一个位置(不在同一个机房)

数据迁移

当DataServer增加时,config server负责重新计算一张新的桶在data server上的分布表
将桶较为平均的分配到各个DataServer上
当DataServer发生故障时, config server负责重新计算一张新的桶在data server上的分布表,
将原来由故障机器服务的桶的访问重新指派到其它的data server中
这时需要做数据迁移,具体流程如下:

1、设置当前正在迁移的桶ID
2、DataServer写入桶数据时,会写入redolog
3、migrate_manager迁移内存中的桶数据
4、migrate_manager迁移redolog数据
5、redolog数据迁移完成后,将桶标记为迁移完成
6、将信息发送给ConfigServer用于同步对照表

Tair存储引擎

Tair的存储引擎有一个抽象层(storage_manager),只要实现存储引擎接口,便可以替换Tair的底层存
储引擎。
可插拔存储引擎—类似MySQL
Tair默认包含四种存储引擎:mdb、fdb、kdb和ldb

mdb

数据存储:Memcached
高效缓存存储
使用share memory ,重启不会数据丢失
支持K-V存储、prefix操作
适用于:String缓存使用 (json)、大访问少量的临时数据存储、Session分离

fdb

数据存储:FireBird
高效的持久化SQL存储
索引文件和数据文件分离------>mysql MyISam
使用Tree的方式根据key的hash值索引数据 B tree
索引文件在内存中
适用于:快速访问较小的数据

kdb

数据存储:Kyoto Cabinet
Cabinet开发的KV的持久化存储

简单的包含记录的数据文件
存储形式为hash表或B+Tree
适用于:简单临时存储

ldb

数据存储:LevelDB
是Google开发的高性能持久化KV存储
可内嵌mdb缓存 mdb+ldb
支持kv、prefix
支持批量操作
适用于:大数据量的存取(交易快照)、高频度的更新(库存)、离线大批量数据导入

rdb

数据存储:Redis
高效缓存存储
多种数据结构和计算
适用于:复杂数据结构存储、商品属性、粉丝列表、商品评论、消息队列

数据存储 持久化 数据格式 应用场景
mdb Memcached K-V存储、prefix操作 缓存使用、Session分离
fdb FireBird SQL、BTree 快速访问较小的数据
kdb Kyoto Cabinet Hash、B+Tree 简单临时存储
ldb LevelDB kv、prefix、batch 大数据量高频度的存储
rdb Redis List、Set、Hash… 复杂数据结构缓存

阿里使用:mdb、rdb、ldb

mdb的存储结构(Memcached)

mem_pool
用于共享内存管理,将内存分为若干个page
page个数根据slab_mem_size设置,单位为MB
单个DataServer最多使用64G内存
mem_cache
用于管理slab,存放slab_manager列表
slab_manager管理item(数据块)
slab个数为100,一个slab可存储800kb
cache_hash_map
用于存储hash表,根据key进行hash对应item数据
hash冲突,产生链表
mdb_area_stat
用于维护area(namespace)状态,记录了该area的数据链表和数据量限制(tablespace)

Tair相应API

key/value常见操作API

命令 操作 说明
get get key [area] 获得key的值
put put key data [area]
[expired]
设置key和value
incr incr key [count]
[initValue] [area]
对key的值自增
decr decr key [count]
[area]
对key的值自减
batcheGet mget key1 … keyn
area
批量获得
expire expire key time 设置key的过期时间
prefixPut pput [area] pkey
skey value
根据前缀设置,按照prefix计算hash,同一个prefix会存
储在同一个hash表,形成链表
prefixGet pget [area] pkey
skey
根据前缀读取

version

Tair中的每个数据都包含版本号,版本号在每次更新后都会递增。这个特性有助于防止由于数据的并发
更新导致的问题,类似于乐观锁
比如,系统有一个value为“a”,A和B同时get到这个value。
A执行操作改为"b"
B执行操作改为"c"
如果不控制,无论A和B谁先更新成功,它的更新都会被后到的更新覆盖。
使用version解决
第一次put version为1
get version为1
A修改成功后 version增加1
B修改时本身version为1,小于服务器版本2
所以B修改不成功
在put时,version传0 可强制修改

struct mdb_item{uint64_t item_id;.....uint16_t version
}

Tair实现乐观锁
trylock(获取版本)–> transaction –> unlock(版本检查) — 正常—> version+1 commit
— 异常—> rollback
只要能获取版本,就认为trylock成功
版本检查则更新version,一般是加1;否则,异常处理,version不变,并开启回滚
多事务同时获得乐观锁时,unlock只能有一个成功,其余的都应该失败
version 初始化要大于1
Tair实现分布式锁
利用 Tair 的 version 特性可以实现分布式锁,由于 LDB 具有持久化功能,当服务有出现宕机的情况,
也不会因此出现锁丢失或者锁不可释放的情况。
如果KEY不存在的话,传入一个固定的初始化VERSION(需要大于1),Tair会在保存这个缓存的同时设
置这个缓存的VERSION为你传入的 VERSION+1
KEY如果已经存在,Tair会校验你传入的VERSION是否等于现在这个缓存的VERSION,如果相等则允许
修改,否则将失败。

    //获得锁public boolean lock(String lockKey) {//10 :version expiretime : 过期时间 秒ResultCode code = defaultTairManager.put(lockKey, defaultVlaue, 5,expiretime);if (ResultCode.SUCCESS.equals(code))return true;elsereturn false;}//释放锁public Boolean unlock(String lockKey){ResultCode code = defaultTairManager.delete(lockKey);return ResultCode.SUCCESS.equals(code);}

Java Client

pom.xml

<!-- https://mvnrepository.com/artifact/com.taobao.tair/tair-client --><dependency><groupId>com.taobao.tair</groupId><artifactId>tair-client</artifactId><version>2.3.5</version></dependency>

demo

    DefaultTairManager defaultTairManager = new DefaultTairManager();List<String> cs = new ArrayList<String>();cs.add("192.168.127.132:5198");defaultTairManager.setConfigServerList(cs);defaultTairManager.setGroupName("group_1");defaultTairManager.init();defaultTairManager.put(0,"name:001","zhangfei");Result<DataEntry> value= defaultTairManager.get(0,"name:001");System.out.println(value);//设置版本0 强制更新 过期时间2秒defaultTairManager.put(0,"name:002","zhaoy",0,2);Result<DataEntry> value2= defaultTairManager.get(0,"name:002");System.out.println(value2);

Tair
机房、负载均衡、数据迁移、不停止服务
更好的可用性和负载均衡
Redis
多数据结构处理、计算
Tair+Redis

[由零开始]Tair 介绍和使用相关推荐

  1. 零信任-深信服零信任aTrust介绍(5)

    ​深信服零信任aTrust介绍 深信服是国内领先的互联网信任服务提供商,也是国内首家通过认证的全球信任服务商.深信服零信任是其中一项核心的信任技术,主要针对身份认证.数字签名.数字证书等方面的信任问题 ...

  2. Tair介绍、使用场景、安装使用以及高可用负载均衡

    一.Tair介绍 1.Tair简介 Tair(Taobao Pair)是淘宝开发的分布式Key-Value存储引擎 服务器端自动负载均衡 分为持久化和非持久化两种方式存储 非持久化:分布式缓存使用 M ...

  3. Python爬虫【零】问题介绍 -- 对“微博辟谣”账号的历史微博进行数据采集

    专题系列导引   爬虫课题描述可见: Python爬虫[零]课题介绍 – 对"微博辟谣"账号的历史微博进行数据采集   课题解决方法: 微博移动版爬虫 Python爬虫[一]爬取移 ...

  4. 从零开始学习docker(零)简单介绍Dockerfile

    如果不使用docker,面临的问题有: 部署非常慢 成本非常高 资源浪费 难于迁移和扩展 可能会被限定硬件厂商 虚拟化技术的优点: 虚拟化技术出现以后,一个物理机可以部署多个App,每个App独立运行 ...

  5. Java源码详解零:HashMap介绍

    文章目录 Java详解(0):HashMap介绍,HashMap的迭代,HashMap的线程安全问题 HashMap介绍 HashMap的迭代 HashMap的线程安全问题 Java详解(0):Has ...

  6. 小白也能看懂的零信任SDP介绍

    SDP出现的背景 SDP全称是Software Defined Perimeter,即软件定义边界,是由国际云安全联盟CSA于2013年提出的基于零信任(Zero Trust)理念的新一代网络安全技术 ...

  7. 43家国内外低代码零代码平台介绍-LowCode低码时代

    随着全球数字化进程的加速,敏捷.灵活.易用的低代码.零代码开发方式成为企业构建应用.系统的重要手段之一,同时宏观数字化经济趋势叠加传统企业数字化转型诉求,为低代码.零代码提供了肥沃的发育"土 ...

  8. Scalar的基础篇(零)简单介绍

    Scala简述:基于jvm的面向对象的函数式多范式编程语言. 详解:以java虚拟机为目标运行环境面向对象和函数式编程完美结合 Scala可以访问任何java类库 并且 Scala融合了静态类型系统. ...

  9. NodeJs从零构建代理ip池(一)介绍

    <原文地址> 本系列主要讲解如何从零实现一个简单的代理 IP 池,教你从 Node 爬虫入门到融会贯通. 跟着本系列教程,将会学到一个完整 NodeJs 项目的开发到部署的一整套流程. 零 ...

最新文章

  1. TechED 2005 博客园兄弟合影
  2. 深入浅出mfc随笔——MFc程序的生死因果
  3. 索尼将成立200亿日元基金 投资机器人、人工智能等新兴企业
  4. android studio 写文件,在Android Studio中从我自己的类读取和写入文本文件
  5. 2020最后一个月,近4成应届生未就业,19个头部城市谁最留不住人?
  6. c#中invoke和beginvoke的区别
  7. P4051-[JSOI2007]字符加密【SA】
  8. form表单用js提前执行函数若不成功则不提交_面试必会的重复提交 8 种解决方案!...
  9. java gc 例子_Java 中, 为什么一个对象的实例方法在执行完成之前其对象可以被 GC 回收?...
  10. 2021 ICPC Asia Jinan Regional Contest-J Determinant(取模高斯消元)
  11. 【Java与智能设备】Ch0402 Activity的生命周期
  12. html代码大全字号,网页设计HTML代码大全
  13. git中将多次commit合并为一次commit
  14. win10更新后IE不见了
  15. 七剑下天山-告别时域分析的过渡课堂练习-SS2022s
  16. 一个有用的webstrom激活方法
  17. mysql和ocrcle_oracle 12.1 RAC的ocr磁盘组异常恢复
  18. Java 处理Hex字符串,SM2验签
  19. POE交换机全方位解读(下)
  20. java utf 8_java utf-8 乱码的解决方法

热门文章

  1. RGB数字信号VESA标准时序verilog设计
  2. API 设计好文收集
  3. Promotion Counting【USACO 2016 January Contest, Bronze】
  4. 中国精细化工行业发展模式与十四五投资战略规划研究报告2022-2028年
  5. shell编程实例-石头剪子布游戏
  6. 停车场管理系统之控制台java实现
  7. 简单粗暴----封装Python自定义库,后续可直接在python和RF中调用
  8. jq 刷新页面,刷新父级页面,iframe刷新父级页面
  9. 浏览器批量采集网站标题 保存Excel表格
  10. hive 和 Hadoop 浅析