我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于内存的关系数据库memsql初探

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于内存的关系数据库memsql初探

基于内存的关系数据库memsql初探

  1. 背景

    1. 广告系统中,算法模型预估需要根据广告的实时转化统计结果,才能做出更精准的预估;同时,支持多维度聚合查询(例如按照广告各个不同层级维度,按照时间不同粒度的维度),并跨大区合并。一开始的版本是基于mysql,但由于统计数据更新太频繁,异步定期从mysql捞统计结果,导致mysql经常出现活跃连接数太多而频频出现告警。
    2. 尝试过很多优化:
      1. 加数据接入层:中间加一层mysql代理服务data access,缓存mysql的统计结果,所有的读请求都从data access获取,可以减少mysql的读压力(也可以从mysql从库读,减少master节点压力,只是没去尝试)
      2. 减少数据量:删除历史的统计数据,只保留业务需要的时间窗口的统计结果
      3. 减少代理的访问频率:即使加了代理(2个节点),但由于mysql需要同步的表数量太多(接近200个),每个表的数据也达到了百万级别,频繁访问也还是会增加mysql的负担,后面不得已采取牺牲统计的时效性,降低对mysql的访问频率
      4. 加入redis作为统计写入的缓存队列:前面提到的基本都是针对读的优化,实时统计的写入量很大,如果没有先聚合,拿到一条就写入一次,一样会导致mysql负载过高。所以在服务中先聚合后再写入,但是,由于聚合是在内存的,要是服务上线重启,临时聚合的数据来不及写入mysql,又会导致数据丢失。。所以采取了写入redis的方式,redis作为缓存队列,保存一天内具体到每一分钟的统计结果,统计程序定期的从redis中捞取结果,再聚合到5分钟,1个小时,1天,1周的维度。可能这里有人会问,为什么不用kafka或者其他主流mq作为缓存队列,由于需要从其他大区把数据捞出来聚合后一起做统计,这个过程可能会由于物理距离原因而超时,导致统计不准,把消费事务设置为 Exactly Once,跨区消费完了后需要发送确认消息,这个延迟比较大。而且,即使能在一次统计中统计正确,但如果前面有其他的统计出现错误,会导致当天的统计一直错下去,没法补数据。如果用redis,只要数据未过期,可以对之前统计的结果重新统计后覆盖,虽然会牺牲一点redis的qps,但redis支持的qps能达到15w,本身性能就很好,所以不是什么大问题。结果就变成了定期的的insert into xx on duplicate xx
    3. 结果
      1. 一系列优化之后,mysql不再告警了,然而,维护的复杂度也变高了,如果需要增加一个维度,redis、data access、上层应用服务都要改一遍,改起来相当麻烦,而且,维度多,也会导致统计的压力变大。
    4. 主角出场
      1. 这阵子在看《数据密集型应用系统设计》,作者是少有的从工业界干到学术界的牛人,书中提到了基于内存的关系数据库memsql,因此做了简单的调研。
  2. memsql简介

    1. 基于内存,宣称是世界上最快的关系数据库,为了避免服务重启后丢数据,数据定期写磁盘,这点类似redis
    2. 支持横向和纵向扩展:纵向使得单机性能更好,横向支持水平扩展
    3. sql解析:sql预编译到C++中,这就要求sql语句不要经常变化,好处就是常用的语句少了解析部分,执行会比较快
    4. ACID:不是full ACID,A:只对单条语句;I:只支持read commited;D:不是每个事务都持久化。C是目标,AID有缺陷,C也在某种程度下不能完全达到
    5. 性能:官方有做测评,但被一个facebook的员工吐槽了(https://dom.as/2012/06/26/memsql-rage/,知乎有人对观点做了总结:https://zhuanlan.zhihu.com/p/49159963),大概意思就是拿mysql和memsql的不对等的参数做基准测试对比,没有意义。例如:
      1. mysql可以设置 innodb_buffer_pool_size大小,如果设置太小,会导致缓存命中率变低。
      2. mysql设置事务落磁盘的频率: innodb_flush_log_at_trx_commit,频率太高也会影响性能
      3. 最坑的是:由于memsql是以skiplist存的,如果要order by获取pk最大的元素(定义表是asc),则需要排序,这在mysql中不需要排序。不过,这个问题貌似后来已经修复了(见知乎的评论:)
    6. 高可用:支持双机备份
    7. 有人说,如果把mysql的表的存储引擎设置为memory,而且设置触发器写磁盘,不就可以代替memsql了吗?于是有人正对innodb、memory、memsql的性能做了测评,请看以下的测评报告。
    8. 性能测评:
      1. 直接说结论:在增删改查都执行的情况下,qps分别是:
        数据库/引擎 mysql innodb mysql memory memsql
        qps 750 10k 50k
        如果仅仅是追求性能,牺牲部分ACID特性,还是可以试试。
      2. 测评过程录制成youtube视频:https://youtu.be/zKh8CsgF1OQ
    9. 但是,这玩意不开源,只有受限制的开发版本(集群总内存不能超过128G)和全功能的商业版本,不开源的情况下,如果使用的不够普遍,而且对其原理不了解的情况下,在生产环境还是不太敢使用。
  3. memsql体验

    1. docker镜像启动:https://github.com/memsql/memsql-docker-quickstart
    2. docker镜像自带基准测试,在开10个并发的情况下,写入qps可以达到140w(当然这个基准测试也是比较水,表字段只有2个)
  4. 总结

    1. 在满足基本功能的情况下追求性能,memsql确实是不错的选择;但是如果对其原理不了解的情况下,在生产环境使用,容易踩坑。
  5. 其他内存数据库

    1.  VoltDB,也是基于内存的关系数据库,也是有收费的商业版和开源版,java写的,特性待调研。
  6. 相关资料

    1. 知乎总结:https://zhuanlan.zhihu.com/p/49159963
    2. facebook工程师吐槽memsql:https://dom.as/2012/06/26/memsql-rage/
    3.  quora:https://www.quora.com/What-benefits-does-MemSQL-offer-over-running-a-MySQL-database-on-ramdisk

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于内存的关系数据库memsql初探

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于内存的关系数据库memsql初探

背景广告系统中,算法模型预估需要根据广告的实时转化统计结果,才能做出更精准的预估;同时,支持多维度聚合查询(例如按照广告各个不同层级维度,按照时间不同粒度的维度),并跨大区合并。一开始的版本是基于mysql,但由于统计数据更新太频繁,异步定期从mysql捞统计
基于内存的关系数据库memsql初探
2019-10-28

基于Golang怎么实现内存数据库

今天小编给大家分享一下基于Golang怎么实现内存数据库的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。GO实现内存数据库实现
2023-07-05

Oracle Value函数与内存数据库的关系

Oracle Value函数与内存数据库之间存在一定的关系,但它们并非直接相关。下面我将分别解释这两个概念,并探讨它们之间的联系。Oracle Value函数:Oracle Value函数是Oracle数据库中的一个内置函数,用于将一个值从
Oracle Value函数与内存数据库的关系
2024-10-08

关于初识MySQL数据库以及MySQL的基本使用

文章目录 什么是数据库什么是MySQL为什么要有数据库 MySQL基本使用连接mysql查看当前服务器对应的数据库创建数据库进入某个数据库建立一张表向表中插入数据查询表中的数据 服务器,数据库,表之间的关系数据逻辑存储MyS
2023-08-16

Oracle变量与数据库缓存的关系

Oracle中的变量与数据库缓存之间没有直接的关系。数据库缓存主要关注的是数据的存储和访问效率,而变量是存储在内存中的数据项,用于临时存储数据或表达式结果,以便在程序执行过程中使用。以下是关于Oracle数据库缓存的相关信息:Oracle
Oracle变量与数据库缓存的关系
2024-08-27

关系数据库中基本的数据结构指的是什么

关系数据库中基本的数据结构指的是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在关系数据库中,基本的数据结构是“二维表”,表之间的联系通过不同表中的公共字段来体现。关系数据
2023-06-29

当关系的一侧已存在于数据库中时,使用 SQLModel 插入多对多关系对象

问题内容我正在尝试使用 sqlmodel 在数据库中插入记录,其中数据如下所示。一个 house 对象,它有颜色和许多位置。地点也将与许多房屋相关联。输入为:[{"color": "red","locations": [{"type
当关系的一侧已存在于数据库中时,使用 SQLModel 插入多对多关系对象
2024-02-06

编程热搜

目录