面试题百日百刷-HBase中HTable API有没有线程安全问题,在程序是单例还是多例?

Posted demo软件园

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题百日百刷-HBase中HTable API有没有线程安全问题,在程序是单例还是多例?相关的知识,希望对你有一定的参考价值。

锁屏面试题百日百刷,每个工作日坚持更新面试题。请看到最后就能获取你想要的,接下来的是今日的面试题:



 

1.HBase内部机制是什么?

Hbase是一个能适应联机业务的数据库系统

物理存储:hbase的持久化数据是将数据存储在HDFS上。

存储管理:一个表是划分为很多region的,这些region分布式地存放在很多regionserver上Region内部还可以

划分为store,store内部有memstore和storefile。

版本管理:hbase中的数据更新本质上是不断追加新的版本,通过compact操作来做版本间的文件合并Region

的split。

集群管理:ZooKeeper + HMaster + HRegionServer。

2.HTable API有没有线程安全问题,在程序是单例还是多例?

在单线程环境下使用hbase的htable是没有问题,但是突然高并发多线程情况下就可能出现问题。

以下为Htable的API说明:

This class is not thread safe for updates; the underlying write buffer can be corrupted if multiple threads contend over a single HTable instance. 当有多个线程竞争时可能把当前正在写的线程corrupted,那么原因是什么呢?

根据Htable的源码:

public HTable(final byte [] tableName)throws IOException  this(HBaseConfiguration.create(), tableName);public static Configuration create()   Configuration conf = new Configuration();  return addHbaseResources(conf);

 

从上面我们可以看到每一个HTable的实例化过程都要创建一个新的conf,我们甚至可以认为一个conf对应的是一个HTable的connection,因此如果客户端对于同一个表,每次新new 一个configuration对象的话,那么意味着这两个HTable虽然操作的是同一个table,但是建立的是两条链接connection,它们的socket不是共用的,在多线程的情况下,经常会有new Htable的情况发生,而每一次的new都可能是一个新的connection,而我们知道zk上的链接是有限制的如果链接达到一定阈值的话,那么新建立的链接很有可能挤掉原先的connection,而导致线程不安全。

因此hbase官方文档建议我们:HTable不是线程安全的。建议使用同一个HBaseConfiguration实例来创建HTable实例,这样可以共享ZooKeeper和socket实例。例如,最好这样做:

HBaseConfiguration conf = HBaseConfiguration.create();HTable table1 = new HTable(conf, "myTable");HTable table2 = new HTable(conf, "myTable");

 

而不是这样:

HBaseConfiguration conf1 = HBaseConfiguration.create();HTable table1 = new HTable(conf1, "myTable");HBaseConfiguration conf2 = HBaseConfiguration.create();HTable table2 = new HTable(conf2, "myTable");

 

当然最方便的方法就是使用HTablepool了,维持一个线程安全的map里面存放的是tablename和其引用的映射,可以认为是一个简单的计数器,当需要new 一个HTable实例时直接从该pool中取,用完放回。

3.HBase有没有并发问题?

针对HBase在高并发情况下的性能,我们进行如下测试:

测试版本:hbase 0.94.1、 hadoop 1.0.2、 jdk-6u32-linux-x64.bin、snappy-1.0.5.tar.gz

测试hbase搭建:14台存储机器+2台master、DataNode和regionserver放在一起。

测试一:高并发读(4w+/s) + 少量写(允许分拆、负载均衡)

症状:1-2天后,hbase挂掉(系统性能极差,不到正常的10%)。其实并非全部挂掉,而是某些regionserver挂了,并在几个小时内引发其他regionserver挂掉。系统无法恢复:单独启regionserver无法恢复正常。重启后正常。

测试二:高并发读(4w+/s)

症状:1-2天后,hbase挂掉(系统性能极差,不到正常的10%)。后发现是由于zookeeper.session.timeout设置不正确导致(参见regionserver部分:http://hbase.apache.org/book.html#trouble)。重启后正常。

测试三:高并发读(4w+/s)

症状:1-2天后,hbase挂掉(系统性能极差,不到正常的10%)。从log未看出问题,但regionserver宕机,且datanode也宕机。重启后正常。

测试四:高并发读(4w+/s)+禁止分拆、禁止majorcompaction、禁止负载均衡(balance_switch命令)症状:1-2天后,hbase挂掉(系统性能极差,不到正常的10%)。从log未看出问题,但regionserver宕机,且datanode也宕机。重启后正常。

测试期间,还发现过:无法获取".MATE."表的内容(想知道regionserver的分布情况)、hbase无法正确停止、hbase无法正确启动(日志恢复失败,文件错误,最终手动删除日志重启)。

 

全部内容在[git](https://gitee.com/zjlalaforgit/interview)上,了解更多请点我头像或到我的主页去获得,谢谢

锁屏面试题百日百刷-Redis篇

锁屏面试题百日百刷,每个工作日坚持更新面试题。锁屏面试题app、小程序现已上线,官网地址:https://www.demosoftware.cc/#/introductionPage。已收录了每日更新的面试题的所有内容,还包含特色的解锁屏幕复习面试题、每日编程题目邮件推送等功能。让你在面试中先人一步,吊打面试官!接下来的是今日的面试题:

====都有哪些办法可以降低 Redis 的内存使用情况呢?
如果你使用的是 32 位的 Redis 实例,可以好好利用 Hash,list,sorted set,set 等集合类型数据, 因为通常情况下很多小的 Key-Value 可以用更紧凑的方式存放到一起。

====Redis 的内存用完了会发生什么?
如果达到设置的上限,Redis 的写命令会返回错误信息( 但是读命令还可以正常返回。) 或者你可以将 Redis 当缓存来使用配置淘汰机制, 当 Redis 达到内存上限时会冲刷掉旧的内容。

====一个 Redis 实例最多能存放多少的 keys?List、Set、SortedSet 他们最多能存放多少元素?
理论上 Redis 可以处理多达 2^32 的 keys,并且在实际中进行了测试,每个实例至少存放了 2 亿 5千万的 keys。我们正在测试一些较大的值。任何 list、set、和 sorted set 都可以放 2^32 个元素。换句话说,Redis 的存储极限是系统中的可用内存值。

====MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证redis 中的数据都是热点数据?
Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。面试官后面可能就会问到淘汰策略了。。。

====假如 Redis 里面有 1 亿个key,其中有 10w 个key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?
使用 keys 指令可以扫出指定模式的 key 列表。
对方接着追问: 如果这个 redis 正在给线上的业务提供服务, 那使用 keys 指令会有什么问题?
这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕, 服务才能恢复。这个时候可以使用 scan 指令, scan 指令可以无阻塞的提取出指定模式的 key 列表, 但是会有一定的重复概率, 在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。

====如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,redis 可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值, 使得过期时间分散一些。

====使用过 Redis 做异步队列么,你是怎么用的?
一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。当 lpop 没有消息的时候, 要适当sleep 一会再重试。
如果对方追问可不可以不用 sleep 呢?
list 还有个指令叫 blpop,在没有消息的时候,它会阻塞住直到消息到来。如果对方追问能不能生产一次消费多次呢? 使用 pub/sub 主题订阅者模式, 可以实现1:N 的消息队列。
如果对方追问 pub/sub 有什么缺点?
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如 RabbitMQ 等。
如果对方追问 redis 如何实现延时队列?
我估计现在你很想把面试官一棒打死如果你手上有一根棒球棍的话,怎么问的这么详细。但是你很克制,然后神态自若的回答道:使用 sortedset,拿时间戳作为score,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。到这里, 面试官暗地里已经对你竖起了大拇指。但是他不知道的是此刻你却竖起了中指, 在椅子背后。

更多面试题或学习资源可查看我主页或评论获取

以上是关于面试题百日百刷-HBase中HTable API有没有线程安全问题,在程序是单例还是多例?的主要内容,如果未能解决你的问题,请参考以下文章

锁屏面试题百日百刷-Redis篇

面试题百日百刷-kafka篇

锁屏面试题百日百刷-网络篇

面试题百日百刷-kafka篇

锁屏面试题百日百刷-tomcat优化相关

锁屏面试题百日百刷-Redis篇