【架构选型】--HBase、MongoDB、Redis和ES的应⽤场景选
择
⽬录
HBase、MongoDB、ElasitcSearch和Redis 都是 NoSql 数据库,各有千秋,应⽤场景也不同。
1 HBase-2008年初始版本
1.1 特点
1.1.1 容量⼤
传统关系型数据库,单表不会超过五百万,超过要做分表分库,不会超过30列。
Hbase单表可以有百亿⾏、百万列,数据矩阵横向和纵向两个维度所⽀持的数据量级都⾮常具有弹性。
1.1.2 ⾯向列
⾯向列的存储和权限控制,并⽀持独⽴检索,可以动态增加列,即,可单独对列进⾏各⽅⾯的操作 列式
存储,其数据在表中是按照某列存储的,这样在查询只需要少数⼏个字段的时候,能⼤⼤减少读取的数量。
1.1.3 多版本
Hbase的每⼀个列的数据存储有多个Version,⽐如住址列,可能有多个变更,所以该列可以有多个version
1.1.4 稀疏性
为空的列并不占⽤存储空间,表可以设计的⾮常稀疏。不必像关系型数据库那样需要预先知道所有列名然后再进⾏null填充
1.1.5 拓展性
底层依赖HDFS,当磁盘空间不⾜的时候,只需要动态增加datanode节点服务(机器)就可以了
1.1.6 ⾼可靠性
WAL机制,保证数据写⼊的时候不会因为集异常⽽导致写⼊数据丢失。
Replication机制,保证了在集出现严重的问题时候,数据不会发⽣丢失或者损坏。
Hbase底层使⽤HDFS,本⾝也有备份。
1.1.7 ⾼性能
底层的LSM数据结构和RowKey有序排列等架构上的独特设计,使得Hbase写⼊性能⾮常⾼。 Region切分、主键索引、缓存机制使得Hbase在海量数据下具备⼀定的随机读取性能,该性能针对Rowkey的查询能够到达毫秒级别。
LSM树,树形结构,最末端的⼦节点是以内存的⽅式进⾏存储的,内存中的⼩树会flush到磁盘中(当⼦节点达到⼀定阈值以后,会放到磁盘中,且存⼊的过程会进⾏实时merge成⼀个主节点,然后磁盘中的树定期会做merge操作,合并成⼀棵⼤树,以优化读性能。)
1.2 缺点(与关系性数据库对⽐)
不⽀持复杂查询,如条件查询,只⽀持按照row key来查询
容易产⽣单点故障(在只使⽤⼀个HMaster的时候),HA 的master 可以避免
不⽀持事务
JOIN不是数据库层⽀持的,⽽需要⽤MapRecue
只能在主键上索引和排序
没有内置的⾝份和权限认证,需要外部⽀持
1.3 应⽤场景
1. 写密集型应⽤,每天写⼊量巨⼤(上千万或者上亿⾏,每⽇ TB 以上数据量),⽽相对读数量较⼩的应⽤,⽐如游戏的⽇志,DNS信息等
2. 不需要复杂查询条件来查询数据的应⽤,HBase只⽀持基于rowkey的查询,对于HBase来说,单条记录或者⼩范围的查询是可以接受的,⼤范围的查询由于分布式的原因,可能在性能上有点影响,⽽对于像SQL的join等查询,HBase⽆法⽀持。
3. 对性能和可靠性要求⾮常⾼的应⽤,由于HBase本⾝没有单点故障,可⽤性⾮常⾼。
1.4 FAQ
注意
⾯向列,容量⼤,写⼊⽐mysql快但是读取没有mysql快,超过五百万条数据,则建议读写⽤HBase
业务可不依赖 RDBMS 的额外特性。例如,列数据类型、第⼆索引、事务、⾼级查询语⾔等
确保有⾜够的硬件。因为HDFS在⼩于5个数据节点时,基本上体现不出来它的优势
2 MongoDB-2009年初始版本
2.1 特点
弱⼀致性(最终⼀致),更能保证⽤户的访问速度
⽂档结构的存储⽅式,能够更便捷的获取数据
内置GridFS,⽀持⼤容量的存储
内置Sharding
第三⽅⽀持丰富
2.2 缺点(与关系性数据库对⽐)
2.2.1 acid事务
mongodb 4.0以前不⽀持 acid 事务操作
2.2.2 运维
MongoDB没有如MySQL那样成熟的维护⼯具,这对于开发和IT运营都是个值得注意的地⽅。
在集分⽚中的数据分布不均匀
单机可靠性⽐较差
⼤数据量持续插⼊,写⼊性能有较⼤波动
redis支持的数据结构2.2.3 mongodb占⽤空间过⼤
关于其原因,在官⽅的FAQ中,提到有如下⼏个⽅⾯:
空间的预分配:为避免形成过多的硬盘碎⽚,mongodb每次空间不⾜时都会申请⽣成⼀⼤块的硬盘空间,⽽且申请的量从64M、128M、256M那样的指数递增,直到2G为单个⽂件的最⼤体积。随着数据量的增加,你可以在其数据⽬录⾥看到这些整块⽣成容量不断递增的⽂件。
字段名所占⽤的空间:为了保持每个记录内的结构信息⽤于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果value域相对于key域并不⼤,⽐如存放数值型的数据,则数据的overhead是最⼤的。⼀种减少空间占⽤的⽅法是把字段名尽量取短⼀些,这样占⽤空间就⼩了,但这就要求在易读性与空间占⽤上作为权衡了。我曾建议作者把字段名作个index,每个字段名⽤⼀个字节表⽰,这样就不⽤担⼼字段名取多长了。但作者的担忧也不⽆道理,这种索引⽅式需要每次查询得到结果后把索引值跟原值作⼀个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是拿空间来换取时间吧。
删除记录不释放空间:这很容易理解,为避免记录删除后的数据的⼤规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利⽤。
可以定期运⾏db.repairDatabase()来整理记录,但这个过程会⽐较缓慢
2.3 应⽤场景
2.3.1.适⽤场景
⽹站实时数据:实时的插⼊,更新与查询,并具备⽹站实时数据存储所需的复制及⾼度伸缩性。
数据缓存:信息基础设施的缓存层。在系统重启之后,由 MongoDB 搭建的持久化缓存层可以避免下
层的数据源过载。
⼤尺⼨、低价值数据存储:使⽤传统的关系型数据库存储⼀些数据时可能会⽐较昂贵,在此之前,很多时候程序员往往会选择传统的⽂件进⾏存储。
⾼伸缩性场景:由数⼗或数百台服务器组成的数据库。MongoDB 的路线图中已经包含对 MapReduce 引擎的内置⽀持。
对象或 JSON 数据存储: BSON 数据格式⾮常适合⽂档化格式的存储及查询。
2.3.2.不适合场景
⾼度事务性系统:例如银⾏或会计系统。传统的关系型数据库⽬前还是更适⽤于需要⼤量原⼦性复杂事务的应⽤程序
传统的商业智能应⽤:针对特定问题的BI 数据库会对产⽣⾼度优化的查询⽅式。对于此类应⽤,数据仓库可能是更合适的选择
需要复杂SQL 查询的问题
2.4 FAQ
3 Redis-2009年初始版本
3.1 特点
内存数据库,速度快,也⽀持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进⾏使⽤
Redis不仅仅⽀持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
Redis⽀持数据的备份,即master-slave模式的数据备份
⽀持事务
优势
性能极⾼ – Redis能读的速度是110000次/s,写的速度是81000次/s
丰富的数据类型 – Redis⽀持⼆进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作
原⼦ – Redis的所有操作都是原⼦性的,同时Redis还⽀持对⼏个操作合并后的原⼦性执⾏。(事务)
丰富的特性 – Redis还⽀持 publish/subscribe, 通知, key 过期等等特性
3.2 缺点(与关系性数据库对⽐)
由于 Redis 是内存数据库,所以,单台机器,存储的数据量,跟机器本⾝的内存⼤⼩。虽有 Key 过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
redis 是单线程的,单台服务器⽆法充分利⽤多核服务器的CPU
修改配置⽂件,进⾏重启,将硬盘中的数据加载进内存,时间⽐较久。在这个过程中,redis不能提供服务
3.3 应⽤场景
3.3.1 缓存
缓存现在⼏乎是所有中⼤型⽹站都在⽤的必杀技,合理的利⽤缓存不仅能够提升⽹站访问速度,还能⼤⼤降低数据库的压⼒。Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis⽤在缓存的场合⾮常多。
3.3.2 排⾏榜
很多⽹站都有排⾏榜应⽤的,如京东的⽉度销量榜单、商品按时间的上新排⾏榜等。Redis提供的有序集合数据类构能实现各种复杂的排⾏榜应⽤。
3.3.3 计数器
什么是计数器,如电商⽹站商品的浏览量、视频⽹站视频的播放数等。为了保证数据实时效,每次浏览都得给+1,并发量⾼时如果每次都请求数据库操作⽆疑是种挑战和压⼒。Redis提供的incr命令来实现计数器功能,内存操作,性能⾮常好,⾮常适⽤于这些计数场景。
3.3.4 分布式会话
集模式下,在应⽤不多的情况下⼀般使⽤容器⾃带的session复制功能就能满⾜,当应⽤增多相对复杂的系统中,⼀般都会搭建以Redis 等内存数据库为中⼼的session服务,session不再由容器管理,⽽是由session服务及内存数据库管理。
3.3.5 分布式锁
在很多互联⽹公司中都使⽤了分布式技术,分布式技术带来的技术挑战是对同⼀个资源的并发访问,如全局ID、减库存、秒杀等场景,并发量不⼤的场景可以使⽤数据库的悲观锁、乐观锁来实现,但在并发量⾼的场合中,利⽤数据库锁来控制资源的并发访问是不太理想的,⼤⼤影响了数据库的性能。
可以利⽤Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败,实际应⽤中要考虑的细节要更多。
3.3.6 社交⽹络
点赞、踩、关注/被关注、共同好友等是社交⽹站的基本功能,社交⽹站的访问量通常来说⽐较⼤,⽽且传统的关系数据库类型不适合存储这种类型的数据,Redis提供的哈希、集合等数据结构能很⽅便的的实现这些功能。
3.3.7 最新列表
Redis列表结构,LPUSH可以在列表头部插⼊⼀个内容ID作为关键字,LTRIM可⽤来限制列表的数量,这样列表永远为N个ID,⽆需查询最新的列表,直接根据ID去到对应的内容页即可。
3.3.8 消息系统
消息队列是⼤型⽹站必⽤中间件,如ActiveMQ、RabbitMQ、Kafka等流⾏的消息队列中间件,主要⽤于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现⼀个简单的消息队列系统。另外,这个不能和专业的消息中间件相⽐。
3.4 FAQ
4 ES-2010年初始版本
4.1 优点
功能全⾯
Restful API
扩展性强
⽀持复杂查询
4.2 缺点
字段类型⽆法修改、写⼊性能较低和⾼硬件资源消耗
各节点数据的⼀致性问题:其默认的机制是通过多播机制,同步元数据信息,但是在⽐较繁忙的集中,可能会由于⽹络的阻塞,或者节点处理能⼒达到饱和,导致各数据节点数据不⼀致——也就是所谓的脑裂问题,这样会使得集处于不⼀致状态。⽬前并没有⼀个彻底的⽅案来解决这个问题,但是可以通过参数配置和节点⾓⾊配置来缓解这种情况。
没有细致的权限管理,也就是说,没有像mysql那样的分各种⽤户,每个⽤户⼜有不同的权限。所以在操作上的限制需要⾃⼰开发⼀个系统化来完成。
4.3 应⽤场景
⽇志分析
⽹站服务器、移动设备、IOT 传感器等设备产⽣的⽇志都存在节点分散、种类多样、规模庞⼤等问题,这对需要通过⽇志搜索进⾏异常问题定位和业务分析等⼯作造成了很⼤的挑战。ES 提供了弹性可扩展、实时的集中式存储⽅案以及全⽂搜索功能,⽅便⽇志的统⼀管理和查询,帮助⽤户快速定位和发现问题,提⾼解决问题的效率。
全⽂检索
电商商品搜索、移动应⽤搜索、企业内部信息搜索等海量数据下的站内搜索服务是⾼效获取信息的必要途径,ES 拥有全⽂检索功能,对结构化和⾮结构化数据都有良好的⽀持,同时还提供了简单易⽤的 RESTful API 和各种语⾔的客户端,⽅便⽤户快速搭建稳定的搜索服务,整合到已有的业务框架中。
商业智能 BI
在数据驱动运营的⾏业背景下,电⼦商务、移动应⽤、⼴告媒体等业务都需要借助数据分析和数据挖掘来辅助商业决策,⽽规模庞⼤的业务数据对数据的统计分析造成了很⼤的挑战。ES 拥有结构化查询的能⼒,⽀持复杂的过滤和聚合统计功能,帮助客户对海量数据进⾏⾼效地个性化统计分析、发现问题与机会、辅助商业决策,让数据产⽣真正的价值。
4.4 FAQ
5 总结
如何在 Redis、Mongodb、ES和 HBase 中进⾏技术选型,如下:
Redis:如果你对数据的读写要求极⾼,并且你的数据规模不⼤,也不需要长期存储,选redis;
MongoDB:如果你的数据规模较⼤,对数据的读性能要求很⾼,数据表的结构需要经常变,有时还需要做⼀些聚合查询,选MongoDB;
ES:如果你需要构造⼀个搜索引擎或者你想搞⼀个看着⾼⼤上的数据可视化平台,并且你的数据有⼀定的分析价值或者你的⽼板是⼟豪,选ElasticSearch;
HBase:如果你需要存储海量数据,连你⾃⼰都不知道你的数据规模将来会增长多么⼤,那么选HBase。
数据规模Redis ES MongoDB Hbase
查询性能Hbase ES MongoDB Redis
写⼊性能ES MongoDB Hbase Redis
复杂查询&检索Redis Hbase MongoDB ES
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论