0%

HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
HBase访问接口如下:

  1. Native Java API,最常规和高效的访问方式,适合Hadoop MapReduce Job并行批处理HBase表数据
  2. HBase Shell,HBase的命令行工具,最简单的接口,适合HBase管理使用
  3. Thrift Gateway,利用Thrift序列化技术,支持C++,PHP,Python等多种语言,适合其他异构系统在线访问HBase表数据
  4. REST Gateway,支持REST 风格的Http API访问HBase, 解除了语言限制
  5. Pig,可以使用Pig Latin流式编程语言来操作HBase中的数据,和Hive类似,本质最终也是编译成MapReduce Job来处理HBase表数据,适合做数据统计
  6. Hive,当前Hive的Release版本尚没有加入对HBase的支持,在Hive 0.7.0中支持HBase,可以使用类似SQL语言来访问HBase
    本文针对HBase Shell,做一个详细讲解。
阅读全文 »

HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用 Chubby作为协同服务,HBase利用Zookeeper作为对应。

阅读全文 »

Info信息


以下信息是在redis-cli中执行info命令,可能和redis cluster版本有点不同的地方,仅此作为参考。

阅读全文 »

内存淘汰


获取内存淘汰配置策略

1
127.0.0.1:6379>config get maxmemory-policy
  • volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据。
  • volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰。
  • volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰。
  • allkeys-lru:使用LRU算法从所有数据集合中淘汰数据。
  • allkeys-random:从数据集合中任意选择数据淘汰
  • no-enviction:禁止淘汰数据。

延时追踪及慢查询


Redis的延迟数据是无法从info信息中获取的。倘若想要查看延迟时间,可以用 Redis-cli工具加–latency参数运行,如:

1
Redis-cli --latency -h 127.0.0.1 -p 6379

结果为查询ID、发生时间、运行时长和原命令 默认10毫秒,默认只保留最后的128条。单线程的模型下,一个请求占掉10毫秒是件大事情,注意设置和显示的单位为微秒,注意这个时间是不包含网络延迟的。

1
127.0.0.1:6379>slowlog get

查看aof是否影响延迟,在info Stats中查看,数字代表有多少次fork延迟操作

1
2
latest_fork_usec:1724##单位微妙

查看最近一次fork延迟耗时

1
aof_delayed_fsync:0###被延迟的 fsync 调用数量

主从切换

在运维过程中,整体断电后,集群重启后,master与slave节点分布可能会出现变化,为了保证集群master分布均匀,可使用命令主动切换master.
在需要提升为master的节点执行以下命令

1
127.0.0.1:6379>cluster failover

指定slave数量

可在redis.conf中配置

1
cluster-migration-barrier 1

该参数指定slave最小数量为1,当前节点无法满足的话,会从别的节点漂移一个作为master的slave

Hbase学习

Hbase shell操作

一、建表

1.新建不带namespace表

1
create 'testTable','t1','t2'

2.新建带namespace表

  • 首先建一个namespace
    1
    create_namespace 'truman'
  • 其次再新建表
    1
    create_namespace 'truman:test','t1','t2'
    备注:t1,t2为column family
    1
    2
    create'reason:user_test','bs',{NUMREGIONS=>2,SPLITALGO=>'HexStringSplit'}

二、查表

  • 列出所有表
    1
    list
  • 浏览某个表
    1
    scan 'testTable'

三、数据操作

  • 增加数据
    1
    2
    3
    put 'testTable','row1','t1:name','value1'
    put 'testTable','row2','t1:name','value2'
    put 'testTable','row3','t1:name','value3'
  • 获取数据
    1
    get 'testTable','row1'
  • 删除数据
    1

其他

待完善

参考

1.https://hbase.apache.org/book.html

利用winscp与putty构建自动化部署

前言

在运维过程中,会经常遇到维护的机器很多,更新软件版本比较繁杂,在此借鉴winscp与putty支持脚本的功能之上,使用window bat命令实现在window平台便捷部署linux上的应用。

方案

上传文件

此处利用winscp。updateLoadScript.txt 具体操作代码如下:

1
2
3
4
5
6
7
option batch on 
option confirm off
open scp://root:12345678@192.168.*.**
put E:\deploy\tt.txt /data/projects/
close
exit

此处主要,要提前用winscp连接到相应主机上,猜测要从缓存中取一些东西

执行命令

此处利用 putty。 command.txt 具体命令如下:

1
2
3
4
5
6
7
export JAVA_HOME=/opt/jdk1.8.0_45
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
cd /data/projects/redis-client
./start.sh stop
./start.sh start
ps -ef|grep redis-client

bat文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@echo off 
echo ===============================
echo deploy RedisClient app
echo ===============================
echo please input "y" to continue......
set /p input=
if "%input%"=="y" (
rem --打开控制台
call D:\WinSCP\WinSCP.exe /script=updateLoadScript.txt /log=upload_log.txt
call D:\WinSCP\PuTTY\putty.exe -ssh -pw 12345678 root@192.168.*.** -m command.txt
call D:\WinSCP\PuTTY\putty.exe -ssh -pw 12345678 root@192.168.*.** -m command.txt
echo deploy RedisClient successed!
) else echo Does not execute any command
pause

参考

  1. winscp 使用 http://www.5iadmin.com/post/1014.html

RedisCluster构建批量操作探讨

前言

众所周知,jedis仅支持redis standalone mset,mget等批量操作,在最新的redis cluster中是不支持的,这个和redis cluster的设计有关,将不同的实例划分不同的槽。不同的key会落到不同的槽上,所在的实例也就不同,这就对jedis的批量操作提出问题,即无法同时支持多个实例上的批量操作。(理解可能不是很深入,希望有人看到可以指教一下)

分布式储存产品存储方式

在分布式存储产品中,哈希存储与顺序存储是两种重要的数据存储和分布方式,这两种方式不同也直接决定了批量获取数据的不同,所以这里需要对这两种数据的分布式方式进行简要说明:

  1. hash分布:
    hash分布应用于大部分key-value系统中,例如memcache, redis-cluster, twemproxy,即使像MySQL在分库分表时候,也经常会用user%100这样的方式。
    hash分布的主要作用是将key均匀的分布到各个机器,所以它的一个特点就是数据分散度较高,实现方式通常是hash(key)得到的整数再和分布式节点的某台机器做映射,以redis-cluster为例子:

    问题:和业务没什么关系,不支持范围查询。
  2. 顺序分布
  3. 两种分布方式的比较:
分布方式 特点 典型产品
哈希分布 1. 数据分散度高
2.键值分布与业务无关
3.无法顺序访问
4.支持批量操作
一致性哈希memcache
redisCluster其他缓存产品
顺序分布 1.数据分散度易倾斜
2.键值分布与业务相关
3.可以顺序访问
4.支持批量操作
BigTable
Hbase

分布式缓存/存储四种Mget解决方案

1. IO的优化思路:

  • 命令本身的效率:例如sql优化,命令优化
  • 网络次数:减少通信次数
  • 降低接入成本:长连/连接池,NIO等。
  • IO访问合并:O(n)到O(1)过程:批量接口(mget),

2. 如果只考虑减少网络次数的话,mget会有如下模型:

3. 四种解决方案:

(1).串行mget

将Mget操作(n个key)拆分为逐次执行N次get操作, 很明显这种操作时间复杂度较高,它的操作时间=n次网络时间+n次命令时间,网络次数是n,很显然这种方案不是最优的,但是足够简单。

(2). 串行IO

将Mget操作(n个key),利用已知的hash函数算出key对应的节点,这样就可以得到一个这样的关系:Map<node, somekeys>,也就是每个节点对应的一些keys 。它的操作时间=node次网络时间+n次命令时间,网络次数是node的个数,很明显这种方案比第一种要好很多,但是如果节点数足够多,还是有一定的性能问题。

(3). 并行IO

此方案是将方案(2)中的最后一步,改为多线程执行,网络次数虽然还是nodes.size(),但网络时间变为o(1),但是这种方案会增加编程的复杂度。它的操作时间=1次网络时间+n次命令时间

(4).hash-tag实现

第二节提到过,由于hash函数会造成key随机分配到各个节点,那么有没有一种方法能够强制一些key到指定节点到指定的节点呢? redis提供了这样的功能,叫做hash-tag。什么意思呢?假如我们现在使用的是redis-cluster(10个redis节点组成),我们现在有1000个k-v,那么按照hash函数(crc16)规则,这1000个key会被打散到10个节点上,那么时间复杂度还是上述(1)~(3)

那么我们能不能像使用单机redis一样,一次IO将所有的key取出来呢?hash-tag提供了这样的功能,如果将上述的key改为如下,也就是用大括号括起来相同的内容,那么这些key就会到指定的一个节点上。
例如:

例如下图:它的操作时间=1次网络时间+n次命令时间

4. 四种批量操作解决方案对比:

方案 优点 缺点 网络IO
串行mget 1.编程简单
2.少量keys,性能满足要求
大量keys请求延迟严重 o(keys)
串行IO 1.编程简单
2.少量节点,性能满足要求
大量node延迟严重 o(nodes)
并行IO 1.利用并行特性
2.延迟取决于最慢的节点
1.编程复杂
2.超时定位较难
o(max_slow(node))
hash tags 性能最高 1.tag-key业务维护成本较高
2.tag分布容易出现数据倾斜
o(1)

总结

目前我们项目中采用第一种方式,使用多线程解决批量问题,减少带宽时延,提高效率,这种做法就如上面所说简单便捷(我们目前批量操作类型比较多),有效。但问题比较明显。批量操作数量不大即可满足。最近研究cachecloud发现搜狐他们采用第二点,先将key获取槽点,然后分node pipeline操作。这种做法相对比第一种做法较优。推荐第二种方法,后期对性能有要求的话,考虑修改成第二种方式。
附加cachecloud-client代码中mget追踪路径
类PipelineCluster======>mget======>类pipelineCommand=====>run=====>getPoolKeyMap====>getResult

参考

[1]http://carlosfu.iteye.com/blog/2263813
[2]https://github.com/sohutv/cachecloud/wiki/5.%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3

storm集群搭建

前言

&#160; &#160; &#160; &#160;Storm 是Twitter的一个开源框架。Storm一个分布式的、容错的实时计算系统。Twitter Storm集群表面上类似于Hadoop集群,Hadoop上运行的是MapReduce Jobs,而Storm运行topologies;但是其本身有很大的区别,最主要的区别在于,Hadoop MapReduce Job运行最终会完结,而Storm topologies处理数据进程理论上是永久存活的,除非你将其Kill掉。
Storm集群中包含两类节点:主控节点(Master Node)和工作节点(Work Node)。其分别对应的角色如下:

  1. 主控节点(Master Node)上运行一个被称为Nimbus的后台程序,它负责在Storm集群内分发代码,分配任务给工作机器,并且负责监控集群运行状态。Nimbus的作用类似于Hadoop中JobTracker的角色。
  2. 每个工作节点(Work Node)上运行一个被称为Supervisor的后台程序。Supervisor负责监听从Nimbus分配给它执行的任务,据此启动或停止执行任务的工作进程。每一个工作进程执行一个Topology的子集;一个运行中的Topology由分布在不同工作节点上的多个工作进程组成。

搭建

准备软件

1
2
3
1.JDK1.8
2.zookeeper-3.4.5-cdh5.6.0
3.Storm0.9.5

JDK安装

详见

Zookeeper集群搭建

1.解压

1
tar xvf zookeeper-3.4.5-cdh5.6.0.tar.gz

2.修改配置
添加修改vonf/zoo.cfg

1
cp zoo_sample.cfg zoo.cfg

修改zoo.cfg

1
2
3
4
dataDir=/data/truman/zookeeper-3.4.5-cdh5.6.0/data
server.1=lab1:2888:3888
server.2=lab2:2888:3888
server.3=lab3:2888:3888

在dataDir下新增myid文件,内容为相对应的server后面的数字
3.分发远程主机

1
2
3
scp -r zookeeper-3.4.5-cdh5.6.0 root@lab30:/data/truman/ 
scp -r zookeeper-3.4.5-cdh5.6.0 root@lab31:/data/truman/
scp -r zookeeper-3.4.5-cdh5.6.0 root@lab29:/data/truman/

4.启动和停止
启动命令

1
zkServer.sh start

停止

1
zkServer.sh stop

storm集群安装

在nimbus与supervisor节点上重复以下操作
1.修改配置

  • storm.zookeeper.servers: 因为Storm所有的信息都是存储在Zookeeper中的,所以要指定Zookeeper服务器的地址
    1
    2
    3
    4
    storm.zookeeper.servers:
    - "192.168.0.2"
    - "192.168.0.3"
    - "192.168.0.4"
  • storm.local.dir:
    Nimbus和 Supervisor守护进程需要一个目录来存储一些状态信息,例如( jars, confs, and things like that )
    1
    storm.local.dir: "/data/storm"
  • nimbus.host:
    worker需要知道那一台机器是master,从而可以下载 topology jars 和confs
    1
    nimbus.host: "192.168.0.2"
  • supervisor.slots.ports
    对于每一个supervisor机器,我们可以通过这项来配置运行多少worker在这台机器上。每一个worker使用一个单独的port来接受消息,这个端口同样定义了那些端口是开放使用的。如果你在这里定义了5个端口,就意味着这个supervisor节点上最多可以运行5个worker。如果定义3个端口,则意味着最多可以运行3个worker。在默认情况下(即配置在defaults.yaml中),会有有四个workers运行在 6700, 6701, 6702, and 6703端口。例如:
    1
    2
    3
    4
    5
    supervisor.slots.ports:
    - 6700
    - 6701
    - 6702
    - 6703
    要注意的是:supervisor并不会在启动时就立即启动这四个worker。而是接受到分配的任务时,才会启动,具体启动几个worker也要根据我们Topology在这个supervisor需要几个worker来确定。如果指定Topology只会由一个worker执行,那么supervisor就启动一个worker,并不会启动所有。
  • ui端口
    1
    ui.port: 8998
    2.启动集群
    主节点:执行以下命令
    1
    2
    nohup $STORM_HOME/bin/storm nimbus &
    nohup $STORM_HOME/bin/storm ui &

#从节点,执行一下命令

1
nohup $STORM_HOME/bin/storm supervisor &

启动成功后,即可在192.168.0.2:8992 storm ui中查看服务

参考

1.http://www.tianshouzhi.com/api/tutorials/storm/17
2.http://blog.csdn.net/xeseo/article/details/17678829