技术开发 频道

MySQL是更好的NoSQL

  【IT168 技术】本文解释了为什么使用MySQL作为key/value使用要优于相应的NoSQL数据库,并且提供了有关这样使用的相关指南。

  以Wix网站为例,当有人点击一个会跳转到Wix网站的链接时,他的浏览器会发送一个Http请求到Wix服务器,如果这个请求是请求服务器上不同的子域名,比如user.wix.com/site,该服务器需要分析这个请求的网址,根据不同的子域名名称定位到相应的虚拟空间,这个过程需要key/value查询。

  路由表是用来解决这个定位问题,一旦找到对应的站点,该站点对象就被加载使用,该站点可能有复杂的目录结构,比如包含两个子对象列表,每个列表中有很多服务,下图是这个站点案例示意图:

MySQL是更好的NoSQL

  上图其实是一个数据库表模型图,routes是主表,Sites代表不同的虚拟空间网站内容,sub-obj-1..代表该网站内的不同服务内容。

  当我们使用通常的关系数据库模型更新上述几个数据表时,我们需要使用事务机制更新多表,这样才能确保几个表的数据一致性,因此我们可能在每个表中设计序列主键 外键或对URL字段设立索引。但是会带来下面问题:

  1. 锁限制了数据表的访问,当需要高吞吐量时,锁会降低我们的性能。

  2. 执行一些SQL查询或join之类查询,会有一定的延迟。

  3.序列主键(Serial key)实际是使用了锁机制,因此会影响写入的吞吐量。

  这些都限制了MySQL的吞吐量和并发性,因此这些缺点,而且这个案例实际是需要一个key/va;ue,因而很多开发人员会使用NoSQL解决方案,NoSQL能提供更好的吞吐量和并发性,即使在稳定性 一致性和可用性上有所牺牲。

  在Wix网站实现中创造性地使用MySQL作为一个key/value存储,能够表现出比上述通用数据模型更好的成绩,包括相对于大多数NoSQL数据库,也就是说,将MySQL作为NoSQL引擎使用,这样的系统有杰出的扩展性 高吞吐量和并发性以及低延迟。下面是这些表现数据:

  1. 吞吐量是200,000RPM数量级

  2.路由表有100,000,000条记录数据量级,10G的存储空间

  3.站点site表有100,000,000 记录,200GB存储空间

  4.读延迟是平均1.0-1.5毫秒(如果在一个数据中心是0.2-.03毫秒)

  注意,相比于大多数key/value数据库,不管开源或者基于云的,1毫秒的延迟是相当令人震撼的,这是使用MySQL实现完成的啊。

  下图是这个傲人实战成绩中的schema数据结构:

MySQL是更好的NoSQL

CREATE TABLE `routes` (
  `route` varchar(255) NOT NULL,
  `site_id` varchar(50) NOT NULL,
  `last_update_date` bigint NOT NULL,
  PRIMARY KEY (`key`),
  KEY (`site_id`)
)
 
CREATE TABLE `sites` (
  `site_id` varchar(50) NOT NULL,
  `owner_id` varchar(50) NOT NULL,
  `schema_version` varchar(10) NOT NULL DEFAULT '1.0',
  `site_data` text NOT NULL,
  `last_update_date` bigint NOT NULL,
  PRIMARY KEY (`site_id`)
) /*ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16*/;

  除了主键之外其他字段都放入了单个blob字段中,也就是site_data这个字段,包括sub-obj表,这里并没有使用序列键 serial key,而是使用了一个 varchar(50)作为主键类型,这是存储客户端应用程序中产生的GUID 值作为主键。

  下面的查询能够获得高吞吐量和低延迟

select * from sites where site_id = (
  select site_id from routes where route = ?
)

  这是根据主键查询,这种嵌套查询语法能够确保我们只要将查询SQL一次性就发送到数据库,实则是运行两条SQL查询。

  这条查询显示平均是1毫秒的稳定性能,而更新是半事务的,无需使用事务机制,这是因为使用insert插入数据到site表,然后才进入route表,直至这两步完成之前,这条记录是不会被查询发现的,这样我们首先插入site表再插入route表,我们就能确保一个一致性的状态,即使在特殊情况下可能在site表中有孤儿数据,也就是site有而route表没有的数据记录。

  使用MySQL作为NoSQL经验指南:

  1. 不要使用事务机制,这会引入锁机制,使用应用程序内的事务机制。

  2. 不要使用序列主键serial key. Serial key会引入锁和复杂的active-active配置.

  3.使用应用程序客户端产生唯一键作为主键,可以使用GUID

  当设计数据表结构用于优化读操作时,下面一些经验供参考:

  1.不要规范化normalize.

  2.只有需要索引的字段才设计为一个字段,如果一个字段不需要索引,将其合并到统一的blob/text类型字段中,比如JSON和XML。

  3.不要使用外键

  4.设计数据表结构能实现一行查询语句。

  5.不要执行性能调整命令,这些性能调整命令会引入锁和downtime当机时间,使用活跃迁移(live migration)。

  当查询数据时:

  1.通过主键或index键查询记录。

  2.不要使用join

  3.不要使用聚合aggregation.

  4.在另外备份上运行自己内部复杂查询(BI, data exploration, etc.),不要在主数据库上运行这些查询。

0
相关文章