[NewLife.XCode]百亿级性能
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。
开源地址:https://github.com/NewLifeX/X(求star, 795+)
大数据投名状
先来看看“大数据演示平台”:http://bigdata.newlifex.com
SQLite单表4亿行订单数据,文件大小26.5G,阿里云1C1G的ECS服务器,由 NewLife.XCode + NewLife.Cube 驱动
如上,在4亿行中查询第1000页,耗时16毫秒。
对于高手来说,这个算不得什么,只要注意好索引就行。
这个“演示平台”建立于两年前,给两家领先物流企业递交了简历,其中一家因SQLite拒绝了,另一家给了数据架构师!
现在,每天1亿个快递包裹在路上,产生大量扫描数据。单表数十亿数据很常见(Oracle按月分区),一款数据产品几亿明细数据比比皆是(MySql分表)。
代码之巅、天外飞仙
再来看一下各种数据库的极致性能,飞仙平台 http://feixian.newlifex.com
SQLite插入第一名 56万tps;
MySql插入第一名 60万tps;
SQLite查询(带缓存)1126万qps;
这是上百人用了各种机器(笔记本、台式机、服务器)调整参数进行大量测试后得到的性能排行榜!
所有测试,由 NewLife.XCode 支持!
实际应用中,即使能达到上述性能十分之一,亦能立于不败之地。有时候甚至还达不到百分之一。
尽管如此,极致性能的研究也给我们的应用方式以及数据库参数设置指明了方向!
索引完备
使用关系型数据库来做大数据,第一步必然是索引!
单表超过1000万数据,任何查询都必须走索引!否则数据库一定跟你说ByeBye!
前面SQLite单表4亿数据,共有两个索引,自增ID作为主键,另外有订单号索引。
大表索引不宜过多,务必以数据的主要使用方式来建立一两个即可,尽量不要超过三个,经索引过滤后的数据尽量控制住1万行以内。
常见大型表索引用法:
1,日志型
订单操作表、快递扫描表、传感数据表等超大日志型数据表,每日数千万到数亿行,只插入不修改,最重要的字段就是时间戳CreateTime,建立索引,同时可以按时间分区分表。
这种大表最常见用法就是根据时间戳去抽取来做业务处理,那就是鼎鼎大名的ETL。处理性能1000~10000tps
更高大上一点,就是抽取数据写入Kafka/RocketMQ,名正言顺进行大数据分析!处理性能10万tps
因工作需要,我们依据时间戳抽取了30天共100亿数据写入Redis,供100+应用进行实时数据分析。处理性能100万tps
抽取数据时以每批次抽取5000~20000行为宜,依次调整查询时间段,重量级蚂蚁调度系统(https://github.com/NewLifeX/AntJob)具备动态步进抽取能力,可自动调节最优抽取间隔。
总结起来一句话:按时间戳轮数据!
2,状态表
订单运单都是有状态数据,在整个生命周期中,状态会多次改变。许多业务往往要求两个或多个状态相匹配,那就要求有一张庞大的状态表。
状态表最合适的主键就是订单号,并且一般分表分库存储,常见分表公式 Crc16(code)%1024,分表数以单表不超过1000万为宜。
使用1024状态表的数据库一般是分布式玩法,比较合适分8库,每个库128表,很多应用服务器各司其职,大家共同操作一张表的几率大减。
3,统计分析表
统计表主键一般由统计日期和分类构成,为了方便可建立字符串ID主键,由 {date}_{cid} 组成,也可以对 date + cid 两个字段建立唯一联合索引。
之所以建立 {date}_{cid} 的ID主键,主要是为了方便写明细数据,无需等待统计表插入后(假如使用自增)才得到统计ID。
明细表一定必须根据统计ID来查,由统计ID跟其它主要业务字段构成主索引。
合理查询
既然有了索引,那么大表的任意查询都必须命中索引(或者部分使用索引) 。
为了索引,为了降低数据库负担,有时候宁可多查一点,先把数据查出来,再在内存里面做二次处理!
大数据的瓶颈一定是数据库,应用服务器往往性能过剩!
因此,完全可以把一部分“计算”由数据库转移到应用服务器之中来进行处理。
大表少用join关联,宁可多次查询;
字段精炼
常听到许多人说每天处理数据多少多少TB/PB,听起来数据分析还可以论斤称?挺尴尬的!
虽然数据库很容易遇到IO瓶颈,但很多人达不到那一步。
数据容量上的优化空间还是极大的。
大表字段精简原则:
- 能存ID就别存Name。经常见到用户、商家、地区等信息,又存ID又存Name,甚至还存一个Code。此时需要XCode的扩展属性
- 适当冗余。为了便于查询,可以适当冗余一些字段,但绝不能滥用。比如商家所在地区,如果查询用不到而只是分析时使用,就不需要保存商家ID以外还保存地区
- 只查询需要的字段。这一点跟XCode推崇 select * 并不相悖,绝大部分百万级以内小表可以这么干,但是千万亿万级大表则需按需查询了。
充分利用缓存
少用join关联,慎用字段冗余,即可大量发挥XCode的缓存优势。
10万乃至100万维表数据可尽量缓存起来,随时配合亿万级大表进行数据分析。
另一方面就是数据库缓存,需要DBA大力支持!
系列教程
NewLife.XCode教程系列[2019版]
- 增删改查入门。快速展现用法,代码配置连接字符串
- 数据模型文件。建立表格字段和索引,名字以及数据类型规范,推荐字段(时间,用户,IP)
- 实体类详解。数据类业务类,泛型基类,接口
- 功能设置。连接字符串,调试开关,SQL日志,慢日志,参数化,执行超时。代码与配置文件设置,连接字符串局部设置
- 反向工程。自动建立数据库数据表
- 数据初始化。InitData写入初始化数据
- 高级增删改。重载拦截,自增字段,Valid验证,实体模型(时间,用户,IP)
- 脏数据。如何产生,怎么利用
- 增量累加。高并发统计
- 事务处理。单表和多表,不同连接,多种写法
- 扩展属性。多表关联,Map映射
- 高级查询。复杂条件,分页,自定义扩展FieldItem,查总记录数,查汇总统计
- 数据层缓存。Sql缓存,更新机制
- 实体缓存。全表整理缓存,更新机制
- 对象缓存。字典缓存,适用用户等数据较多场景。
- 百亿级性能。字段精炼,索引完备,合理查询,充分利用缓存
- 实体工厂。元数据,通用处理程序
- 角色权限。Membership
- 导入导出。Xml,Json,二进制,网络或文件
- 分表分库。常见拆分逻辑
- 高级统计。聚合统计,分组统计
- 批量写入。批量插入,批量Upsert,异步保存
- 实体队列。写入级缓存,提升性能。
- 备份同步。备份数据,恢复数据,同步数据
- 数据服务。提供RPC接口服务,远程执行查询,例如SQLite网络版
- 大数据分析。ETL抽取,调度计算处理,结果持久化
[NewLife.XCode]百亿级性能的更多相关文章
- [NewLife.XCode]分表分库(百亿级大数据存储)
NewLife.XCode是一个有15年历史的开源数据中间件,支持netcore/net45/net40,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量 ...
- 支撑百亿级应用的 NewSQL
支撑百亿级应用的 NewSQL https://zhuanlan.zhihu.com/newsql/ 项目背景 初次接触 TiDB,是通过同程网首席架构师王晓波先生的分享,当时同程网正在使开发和数据库 ...
- cassandra百亿级数据库迁移实践
迁移背景 cassandra集群隔段时间出现rt飙高的问题,带来的影响就是请求cassandra短时间内出现大量超时,这个问题发生已经达到了平均两周一次的频率,已经影响到正常业务了.而出现这些问题的原 ...
- 百亿级小文件存储,JuiceFS 在自动驾驶行业的最佳实践
自动驾驶是最近几年的热门领域,专注于自动驾驶技术的创业公司.新造车企业.传统车厂都在这个领域投入了大量的资源,推动着 L4.L5 级别自动驾驶体验能尽早进入我们的日常生活. 自动驾驶技术实现的核心环节 ...
- Redis百亿级Key存储方案(转)
1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...
- Redis百亿级Key存储方案
1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...
- 【转】百亿级实时大数据分析项目,为什么不用Hadoop?
百亿数量级的大数据项目,软硬件总体预算只有30万左右,需求是进行复杂分析查询,性能要求多数分析请求达到秒级响应. 遇到这样的项目需求,预算不多的情况,似乎只能考虑基于Hadoop来实施. ...
- 百亿级企业级 RPC 框架开源了!
今天给大家介绍给一款性能卓越的 RPC 开源框架,其作者就是我推荐每个 Java 程序员都应该看的<Java 生态核心知识点整理>的原作者张玉龙. 说实话我第一次看到这个资料的时候,就感觉 ...
- [NewLife.XCode]实体列表缓存(最土的方法实现百万级性能)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...
随机推荐
- 基于Django的Rest Framework框架的url控制器
本文目录 一 自定义路由(原始方式) 二 半自动路由(视图类继承ModelViewSet) 三 全自动路由(自动生成路由) 回到目录 一 自定义路由(原始方式) from django.conf.ur ...
- 终结 finalize() 和对象引用
一.finalize() 方法 1. 为什么要有 finalize() 方法? 假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收器只知道释放那些经由 new 分配的内存,所以他 ...
- Java中Set与Set<?>到底区别在哪?
您可能知道,无界通配符 Set<?> 可以容纳任何类型的元素,而原始类型Set也可以容纳任何类型的元素.那它们之间有什么区别呢? 1.关于Set<?>的两个事实 关于Set&l ...
- 网络聊天室---node.js中net网络模块TCP服务端与客户端的使用
//1.简单创建 net服务器 // const net = require("net"); // const server = net.createServer((c)=> ...
- Linux安装最新版Node.js
由于直接yum安装的nodejs版本太低,所以本篇文章向大家介绍在 Linux 上安装 Node.js 最新版的方法. 安装环境 本机系统:CentOS Linux release 7.5 Node. ...
- SSD与HDD、HHD的区别
SSD与HDD.HHD的区别 HDD机械硬盘 SSD固态硬盘 HHD混合硬盘
- Visual Studio 2019 16.1 使用 .NET Core 3.0
一.前言 早在很久之前微软便公布 .NET Core 3.0 将支持开发Winform应用程序等等新特性,现如今 .NET Core 3.0 预览版已经出来第五个预览版了,从 .NET Core 2. ...
- 谈谈EF Core实现数据库迁移
作为程序员,在日常开发中,记忆犹新的莫过于写代码,升级程序.升级程序包含两部分:一是,对服务程序更新:二是,对数据库结构更新.本篇博文主要介绍数据库结构更新,在对数据库升级时,不知道园友们是否有如下经 ...
- 被 GANs 虐千百遍后,我总结出来的 10 条训练经验
一年前,我决定开始探索生成式对抗网络(GANs).自从我对深度学习产生兴趣以来,我就一直对它们很着迷,主要是因为深度学习能做到很多不可置信的事情.当我想到人工智能的时候,GAN是我脑海中最先出现的一个 ...
- swif(六)swift闭包
// // main.swift // LessonSwiftSix // // Created by keyan on 15/9/13. // Copyright (c) 2015年 keyan. ...