Index and Payload

NoMagic 的文档也正在不断的更新 https://github.com/kernel1983/NoMagic/blob/master/README_cn.md 另外我们还有一个示例项目来 https://github.com/kernel1983/pythonic.info 来展示如何使用 NoMagic.

Index and Payload

在开发和使用 NoMagic 框架的过程当中, 我们考虑了各种数据的使用方法. 在实践中, 我们不断对数据库本质的有了更透彻的领悟. 关系型数据库简化了人们对于数据库的操作, 但是在面对一些极端的情况的时候, 回到原点重新思考就非常重要了. 可是讽刺的是, 由于多年的数据库教学, 很多人已经不知道数据库的本质意义了, 显得计算机教育的可悲.

数据库, 数据的仓库. 本质上, 数据存在磁盘上就行了, 但是磁盘上的数据我们给他起了另外一个名字: 文件. 好吧... 那么数据库被人们怎么定义了呢, 能存储数据, 还要能方便的查询数据. 怎么说? 在文件里寻找, 或者说在非结构化数据里面寻找, 叫搜索, 通常效率不是那个高. 在结构化数据里面寻找, 那叫查询. (我写的很随意, 大家轻拍)

数据库最终成为"关系型数据库"的缩写, 因为应用太广泛了. 人们使用计算机最早的两个应用: 写文档和处理表格, 到现在还被不断的重新发明(Office, iWork, Google Docs). 关系型数据库就是一个巨大的表格.

数据存储, 我们称为 Payload, 主要还是依靠文件系统. 查询数据, 我们可以用文件中搜索的方法, 但是, 那样不够高效, 算法的提升也很有限, 硬盘的速度也就那么快. 另外一方面, 人们发明了各种变态的算法和数据结构来缩短数据的寻找时间, 这个技术我们称之为Index, 中文叫索引.

Database = Payload + Index

(我写的很通俗, 大家轻拍)

一个巨大的数据库, 放这个G级别甚至T级别的数据, 却可以接受每秒钟N多次的查询, 并取出数据.

我写这么多不是为了赞扬数据库有多伟大. 相反, 很多数据库设计的很糟糕, 一个查询需要N秒. 一些特别"优秀"的程序员, 通过ORM等技术合成出来的超级复杂的SQL语句(我打赌他们自己看不懂), 在执行的时候需要数十秒甚至几分钟...

任何系统都有一个极限, 一个包只能装一定重量的东西, 一把尺只能量一定长度的距离, 一辆车只能跑到一定的速度. 当我们的数据库和现有的硬件(硬盘)合作, 尽了最大努力也需要很长的时间才能返回结果, 我们就需要问问自己, 是不是要求太多了.

在设计一个能处理很大很大数据系统的时候, 需要充分发挥想象力. 这里的小标题给我的启示是, 既然数据库有两部分, 那么我们把它分开怎么样? 什么样的东西会比传统的数据库更加适合存放 Payload, 文件, 或许是个好主意, 请注意这个思想已经非常久远, 我们上传的照片和头像, 已经早就被从数据库中剥离, 存储在文件系统里了. 继续思考, KV 数据库或许会让我们的系统存储数据的能力加强, 因为这样的数据库系统设计简单, 不需要处理SQL语句, 缺点是编程也比较麻烦.

另外, 如果一台 Payload 服务器的 IO 压力很大怎么办? 其实这些在行业里已经有了共识, 我们用UUID来做数据库的主键吧, 这样就可以分布式的存放数据了.

当我们用 KV 数据库来存储 Payload 的时候, 我们只需要写一个程序, 在传统的 MySQL 里面建立一个索引表. 根据实际业务, 我们可以创造性的做很多事情:

  • 我们不需要索引整个数据库, 如果你的查询只对过去几个月的信息感兴趣, 那么你完全可以建立一个近两个月的小数据表来索引数据.
  • 我们可以更加灵活的建立缓存系统, 充分利用内存和硬盘, 以及网络的速度的差异.
  • 我们可以通过修改表名的方式, 写一个很慢的程序来重建索引, 最后快速的用一个新索引表替换原来的索引表, 避免锁表.

Query vs KV Programming

我们需要在编程方法上革新, 是因为我们已经太依赖索引了. 如果没有 RDBMS, 或许我们可以用更加淳朴的方式编程. 举例:

当我们需要查询用户(ID为1)的所有发帖的时候, 这是一个最简单不过的查询

SELECT * FROM posts WHERE user_id = 1

同时我们必须承认, 即使如此简单基本的查询, 一旦缺少索引技术的支持, 执行时间依然遥遥无期.

在只有 KV 数据库的情况下, 我们是怎么做的? 我们在用户的数据中, 记录下用户的所有 post_ids.

{"name": "John", "post_ids": [1,3,5]}

接着, 如果 KV 数据库有 batch 操作, 我们可以一口气取得数据库表 posts 的记录 1, 3 和 5, 这些是 key 所以完全可以用闪电般的速度完成. 假设我们用 MySQL 作为这里的 KV 数据库的话, 大概是这样的查询:

SELECT * FROM posts WHERE id IN (1, 3, 5)

其中 id 是传说中最快最快的主键.

这里描述的是我们思路的转变, 感觉有点麻烦? 曾经写汇编也麻烦, 慢慢的总有办法克服. 我们只要把这些行为抽象成函数, 起一个人人都能看懂的函数名, 配合命名空间, 最后其实一点都不麻烦.

简单古老的技术基本可以满足我们的大部分需求, 如果说还要加上点什么, 写点测试来保证那些函数正确工作吧.

High Availability

这是我最近的学习体会. 因为在讨论 Paypal 这个金融级别的公司在用什么数据库, 发现 Paypal 已经成为 MySQL 的重要 showcase 案例了. Slideshare 里面也有一些技术的 ppt 展示 Paypal 如何使用 MySQL www.slideshare.net/matkeep/paypal-mysql-cluster.

MySQL 集群的重要特点是 Index 都在机器内存中, 而 Payload 都在磁盘中(研究的不深入, 不对请纠正), 并且高可用.

分片技术能解决系统的线性可扩展性, 但是无法解决数据库的高可用性. MySQL 在这方面提供了热备份和集群两种模式. 热备份出现的比较早, 也被业界广泛接受. 集群技术则出现的比较晚, 并且使用了很多内存解决方案, 在高可用性方面是给力的, 但是基于成本方面的考虑, 没有太多公司会在早期开始投入.

我相信, 分片, 集群和热备份技术综合使用, 那么 MySQL 会是一个非常给力的解决方案. 再结合 web 世界已经通用的 cache 技术, 很多领域都是可以 MySQL 走到黑的. 当然如果更加倾向与其他的新技术来取代 MySQL 数据库的 Payload 或者 Index 部分, 那么则有更大机会创造互联网神话 :)

NoMagic

写了这么多, 主要是为了告诉大家 NoMagic 的主要内容和中心思想. 如果你是因为 NoMagic 才来看这篇博客的, 那么不要紧. 否则, 欢迎查看一下 NoMagic 项目, hosting 在 github 上 https://github.com/kernel1983/NoMagic/blob/master/README_cn.md

blogroll

social