目录
1 HBase-2008年初始版本
1.1 特点
1.2 缺点(与关系性数据库对比)
1.3 应用场景
1.4 FAQ
2 MongoDB-2009年初始版本
2.1 特点
2.2 缺点(与关系性数据库对比)
2.2.1 acid事务
2.2.2 运维
2.2.3 mongodb占用空间过大
2.3 应用场景
2.3.1.适用场景
2.3.2.不适合场景
2.4 FAQ
3 Redis-2009年初始版本
3.1 特点
3.2 缺点(与关系性数据库对比)
3.3 应用场景
3.4 FAQ
4 ES-2010年初始版本
4.1 优点
4.2 缺点
4.3 应用场景
日志分析
全文检索
商业智能 BI
4.4 FAQ
5 总结
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
https://hbase.apache.org/book.html#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运营都是个值得注意的地方。
- 在集群分片中的数据分布不均匀
- 单机可靠性比较差
- 大数据量持续插入,写入性能有较大波动
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
https://www.mongodb.com/faq
注意事项:https://www.huaweicloud.com/articles/bc546fc97713dc4d6cfe8f0898ff170a.html
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
https://redis.io/topics/faq
4 ES-2010年初始版本
4.1 优点
- 功能全面
- Restful API
- 扩展性强
- 支持复杂查询
4.2 缺点
- 字段类型无法修改、写入性能较低和高硬件资源消耗
- 各节点数据的一致性问题:其默认的机制是通过多播机制,同步元数据信息,但是在比较繁忙的集群中,可能会由于网络的阻塞,或者节点处理能力达到饱和,导致各数据节点数据不一致——也就是所谓的脑裂问题,这样会使得集群处于不一致状态。目前并没有一个彻底的方案来解决这个问题,但是可以通过参数配置和节点角色配置来缓解这种情况。
- 没有细致的权限管理,也就是说,没有像mysql那样的分各种用户,每个用户又有不同的权限。所以在操作上的限制需要自己开发一个系统化来完成。
4.3 应用场景
参考:https://cloud.tencent.com/document/product/845/16480
日志分析
- 网站服务器、移动设备、IOT 传感器等设备产生的日志都存在节点分散、种类多样、规模庞大等问题,这对需要通过日志搜索进行异常问题定位和业务分析等工作造成了很大的挑战。ES 提供了弹性可扩展、实时的集中式存储方案以及全文搜索功能,方便日志的统一管理和查询,帮助用户快速定位和发现问题,提高解决问题的效率。
全文检索
- 电商商品搜索、移动应用搜索、企业内部信息搜索等海量数据下的站内搜索服务是高效获取信息的必要途径,ES 拥有全文检索功能,对结构化和非结构化数据都有良好的支持,同时还提供了简单易用的 RESTful API 和各种语言的客户端,方便用户快速搭建稳定的搜索服务,整合到已有的业务框架中。
商业智能 BI
- 在数据驱动运营的行业背景下,电子商务、移动应用、广告媒体等业务都需要借助数据分析和数据挖掘来辅助商业决策,而规模庞大的业务数据对数据的统计分析造成了很大的挑战。ES 拥有结构化查询的能力,支持复杂的过滤和聚合统计功能,帮助客户对海量数据进行高效地个性化统计分析、发现问题与机会、辅助商业决策,让数据产生真正的价值。
4.4 FAQ
https://www.elastic.co/guide/en/cloud/current/ec-faq-getting-started.html
5 总结
如何在 Redis、Mongodb、ES和 HBase 中进行技术选型,如下:
- Redis:如果你对数据的读写要求极高,并且你的数据规模不大,也不需要长期存储,选redis;
- MongoDB:如果你的数据规模较大,对数据的读性能要求很高,数据表的结构需要经常变,有时还需要做一些聚合查询,选MongoDB;
- ES:如果你需要构造一个搜索引擎或者你想搞一个看着高大上的数据可视化平台,并且你的数据有一定的分析价值或者你的老板是土豪,选ElasticSearch;
- HBase:如果你需要存储海量数据,连你自己都不知道你的数据规模将来会增长多么大,那么选HBase。
支持情况 |
Bad |
General |
Good |
Best |
数据规模 |
Redis |
ES |
MongoDB |
Hbase |
查询性能 |
Hbase |
ES |
MongoDB |
Redis |
写入性能 |
ES |
MongoDB |
Hbase |
Redis |
复杂查询&检索 |
Redis |
Hbase |
MongoDB |
ES |