如何选择数据库

此文章来源于同事做的分享

随着公司技术的发展,目前使用的存储种类越来越多。早期使用mysql,后来引入hbase解决数据规模庞大的问题。又因为后端平台业务的需求多变以及厌烦了mysql的分库分表,有引入了MongoDB。再者引入elasticsearch来解决线上搜索业务,以及数据可视化问题。也有同事将活动一类的短期数据存储在Redis中,将其作为线上数据存储。在Redis的4.0发布之前,我们选择了codis解决单机内存不足,业务读取QPS高等问题。

因此目前线上使用的数据库有:

  • MySQL
  • hbase
  • Redis
  • Codis
  • MongoDB
  • ELK

可选种类如此之多,导致开发过过程中,选择合适的存储服务。

MySQL老牌关系型数据库

官方发音为/maɪ ˌɛskjuːˈɛl/“My S-Q-L”[5],但也经常读作/maɪ ˈsiːkwəl/“My Sequel”)原本是一个开放源代码的关系数据库管理系统,原开发者为瑞典的MySQL AB公司,该公司于2008年被Sun Microsystems收购。2009年,Oracle收购Sun Microsystems,MySQL成为Oracle旗下产品。

Oracle并未一家慈善公司。收购Sun Microsystems 公司后,一直在布局新的盈利模式。MYSQL付费版价格提升,组建更大的律师团用于对JVM收费。因此我们可以将目光投向目前社区维护的MariaDB。MariaDB是MySQL的一个分支,仍然是真正的开源产品。

由于MySQL的易用性和性能强大,国内互联网公司都在使用MySQL作为业务存储数据库。我们可以总结一下MySQL的优点:

易用性:

  1. 为多种编程语言提供了API。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。
  2. 提供多语言支持,常见的编码如中文的GB 2312、BIG5,日文的Shift_JIS等都可以用作数据表名和数据列名。
  3. 提供TCP/IP、ODBC和JDBC等多种数据库连接途径。
  4. 既能够作为一个单独的应用程序应用在客户端服务器网络环境中,也能够作为一个库而嵌入到其他的软件中。

运维方便:

  1. 提供用于管理、检查、优化数据库操作的管理工具。
  2. 支持多种架构方式,方便做灾备/负载均衡。支持主从同步,双主一致性架构。

性能强大:

  1. 使用C和C++编写,并使用了多种编译器进行测试,保证源代码的可移植性。
  2. 支持主流的操作系统。
  3. 支持多线程,充分利用CPU资源。
  4. 支持多种存储引擎。
  5. 支持大型的数据库。可以处理拥有上千万条记录的大型数据库。可以支持到GB或者TB级别。
  6. 优化的SQL查询算法,有效地提高查询速度。

mysql提供了事务,对于强一致性要求高,数据要求可靠的业务也会优先采用mysql存储。因此我们大量的基础业务都在mysql上。
对于业务需求稳定。数据字段不会经常增减,字段也非稀疏存在。即使数据量比较大,仍然可以通过分库分表的方式防止单表数据过大。

随着用户增长,业务数据出现急剧增加的情况。比如用户资产数据逐步增大,mysql多次扩充分表单表数据越来越大,运维成本和资源使用开始变得不可控制。这时我们将目光投向了Hbase。

Hbase 为大数据而生

Hbase是Hadoop Database的简称,是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的“Bigtable:A Distributed Storage System for Strctured Data“论文来设计,实现的编程语言为 Java。

HBase在列上实现了BigTable论文提到的压缩算法、内存操作和布隆过滤器。HBase的表能够作为MapReduce任务的输入和输出,可以通过Java API来访问数据,也可以通过REST、Avro或者Thrift的API来访问。

在 Eric Brewer的CAP理论中,HBase属于CP类型的系统。

作为BigTable开源实现的鼎力之作。Hbase具有以下几个优点:

  1. 海量存储,支持PB级别的数据,可以使用廉价的PC存储,极大的降低了数据存储成本。
  2. 高并发,由于HBase采用了region方式将数据切片存储和承接访问,因此可以通过扩充RegionServer来提升整体的并发能力。
  3. 列族存储,存储稀疏字段不占用空间。

区别于传统的RDBMS(关系数据库管理系统 Relational Database Management System),如果想要使用Hbase需要做到以下几点:

  1. 数据足够多,如果预期的数据量比较小,采用Hbase有点牛刀杀鸡了。
  2. 业务上可以不依赖 RDBMS 的额外特性,例如,列数据类型, 二级索引,SQL 查询语言等。
  3. 确保有足够硬件,经典5台服务器部署,2台NameNode(一台主,一台备),3台 DataNode(同时部署ResourceManager, RegionServer)。5台机器都部署ZooKeeper。新版本的Hadoop 可以将NameNode和DataNode混合部署在一起,每台机器都启动NameNode,NameNode Master在ZK中选举产生。

Redis 流行的内存数据库

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。
Redis的外围由一个键、值映射的字典构成。与其他非关系型数据库主要不同在于:Redis中值的类型不仅限于字符串,还支持如下抽象数据类型:

  • list:字符串列表
  • set:无序不重复的字符串集合
  • sorted set:有序不重复的字符串集合
  • hash:键、值都为字符串的哈希表

值的类型决定了值本身支持的操作。Redis支持不同无序、有序的列表,无序、有序的集合间的交集、并集等高级服务器端原子操作。

早期我们主要是用Redis和memcache做缓存服务。两者各有分工,Redis存储短小的字段,memcache存储大字段。随着Redis的使用,对其有了更深层次的了解。公司内也组织集中学习了Redis源码。通过对原理的学习,打消了我们的顾虑。不仅仅把Redis作为缓存服务器,逐渐将一些段时间高请求的数据存储在Redis中。

Redis 本身很高效。对于优化处理速度,redis做了以下几点:

  1. 所有数据都在内存中,并对存储数据结构做了大量优化。
  2. 使用单线程处理前端请求,减少了不必要的上下文切换和锁竞争。
  3. 在linux服务器上采用 Epoll(多路I/O复用模型)。
  4. 采用多种方法来处理数据过期,如:惰性删除:查询已经过期的key,直接删除。同步删除:在处理前端请求时同步删除少量过期的key,达到最大内存时足够多的key。定期删除:定时清理已经到期的key。异步删除:通过 lazyfree 线程删除大key。

Redis也并非银弹。内存数据库始终存在弊端。内存始终有限,无法支持在线扩容。落盘存在延时。宕机之后恢复时间比较长。主从复制并非强一致,宕机存在数据不一致的情况。big key问题也很严重。单个key过大,比如超过10w的zset。在对象申请或者释放内存时会阻塞redis。

如果内存充足,其实线上服务器很难遇到宕机问题。做好主从,使用从库定时备份
针对单机redis 容量有限的问题,调研过redis cluster、twemproxy和codis。考虑客户端需要升级才能支持新的cluster转发协议。并且转发过程存在天然损耗,并且部署运维成本高。

Twemproxy 存在无法平滑地扩容/缩容。
正好赶上Codis主要开发者刘奇来我们公司布道,于是我们开始试用Codis。

Codis

Codis是一个分布式redis集群解决方案。本身采用golang 编写 proxy层,将业务请求转发给后端的 Codis-redis中。起到作用类似于透明代理,对于业务层无感知。无需更改业务代码就能切换到Codis上。

Codis本身不保证数据的有效性。线上常见的是利用主从确保数据不会丢失。引入Group概念,将一组redis master和slave作为一个group,这样当master宕机之后,可以使用工具切换到slave,无需手工操作。

多个Group采用 Pre-sharding 的技术来实现数据的分片, 默认分成 1024 个 slots (0-1023), 对于每个key来说, 通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024。

每一个 slot 都会有一个且必须有一个特定的 server group id 来表示这个 slot 的数据由哪个 server group 来提供。数据的迁移也是以slot为单位的。

优点:

  • 支持常用的redis命令,原生redis协议,无需更改业务代码,无缝迁移。
  • 动态扩容/缩容,增减redis实例,不需要重启服务,用户无感知。
  • 集群管理工具丰富,提供dashboard和命令行工具,方便运维管理。

缺点:

  • 基于原生redis代码,重写了关于slot相关逻辑,无法直接升级后端redis。
  • proxy 基于golang,存在gc问题。会因为gc导致出现抖动。
  • 基于group主从保证数据安全性,可能存在丢失的情况。

我们逐渐将redis业务迁移到Codis中。新部署的业务也从版本2升级到3。

灵活的MongoDB

在这种猪都能漫天乱飞的年代。产品总是能够想出一个新的点子,需求还总是在变化。这时候使用mysql总是遇到上线前要更新表或者补字段。刚刚工作的时候就在想是不是有个数据库不用关心表结构。最终等到了 MongoDB 提出Schema free。

MongoDB是一种面向文档的数据库管理系统,由C++撰写而成,以此来解决应用程序开发社区中的大量现实问题。即提供了传统数据库的功能:二级索引,完整的查询系统以及严格一致性等等。还带来了敏捷性和可扩展性。加速产品上线时间和降低企业成本。

  1. 开箱即用,MongoDB 二进制发布,无需配置即可使用。
  2. 文档类型,业务不用关心数据变化。采用类似于json的bson结构,支持层级式数据。单条数据就可以组合多个业务,因此不需要跨表组装数据。甚至于直接将数据库查询接口使用json编码直接返回给前端。
  3. 内置Sharding,最大支持20PB数据。Replication 复制保证多个副本,不会因为机器故障导致数据丢失。早期数据量不大的时候基本无需运维。
  4. 官方维护多种语言客户端,不担心小语种没有好用的客户端问题。

ELK全面出击

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。

我们最早使用es搭建日志收集平台。使用logstash收集到es中。再通过Kibana 展示给前端。只需要写几个配置文件,就可以得到一个可视化的数据平台。随着业务的增长,后来把业务数据也放到了es中。

ELK 全家桶越来越香。加入Beats套件后改名为
Elastic Stack。组件越来越多,功能也越来越强大。

  • Elasticsearch
  • Kibana
  • Logstash
  • Beats
  • ECE

如何选择数据库

大致介绍完各个存储系统。我们回到最初的问题上,具体业务应该如何选择数据库?

  • MySQL 稳定业务,不涉及分库分表,用到事务
  • Hbase 用户加上资源维度,数据预期超过100亿
  • MongoDB 业务需求多变,数据不到hbase级别但是可能存在分库分表的预期,无事务(mongodb g
  • Codis 缓存,少量高并发的过期数据(配合elk使用)
  • ELK 搜索;业务日志
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350