关于数据库:常用数据库选型你做对了吗

32次阅读

共计 18413 个字符,预计需要花费 47 分钟才能阅读完成。

影响数据库抉择的因素

  • 数据量:是否海量数据,单表数据量太大会考验数据库的性能
  • 数据结构:结构化 (每条记录的构造都一样) 还是非结构化的 (不同记录的构造能够不一样)
  • 是否宽表:一条记录是 10 个域,还是成千盈百个域
  • 数据属性:是根本数据 (比方用户信息)、业务数据 (比方用户行为)、辅助数据 (比方日志)、缓存数据
  • 是否要求事务性:一个事务由多个操作组成,必须全副胜利或全副回滚,不容许局部胜利
  • 实时性:对写提早,或读提早有没有要求,比方有的业务容许写提早高但要求读提早低
  • 查问量:比方有的业务要求查问大量记录的多数列,有的要求查问多数记录的所有列
  • 排序要求:比方有的业务是针对工夫序列操作的
  • 可靠性要求:对数据失落的容忍度
  • 一致性要求:是否要求读到的肯定是最新写入的数据
  • 对增删查改的要求:有的业务要能疾速的对单条数据做增删查改 (比方用户信息),有的要求批量导入,有的不须要批改删除单条记录 (比方日志、用户行为),有的要求检索大量数据 (比方日志),有的要求疾速读取大量数据 (比方展现报表),有的要求大量读取并计算数据 (比方剖析用户行为)
  • 是否须要反对多表操作

不同的业务对数据库有不同的要求

SQL 数据库 & NoSQL 数据库

SQL 数据库就是传统的关系型数据库
  • 行列式表存储
  • 结构化数据
  • 须要预约义数据类型
  • 数据量和查问量都不大,如果数据量大要做分表
  • 对数据一致性、完整性束缚、事务性、可靠性要求比拟高
  • 反对多表 Join 操作
  • 反对多表间的完整性,要删除 A 表的某条数据,可能须要先删除 B 表的某些数据
  • SQL 的增删改查性能强
  • 较为通用,技术比拟成熟
  • 大数据量性能有余
  • 高并发性能有余
  • 无奈利用于非结构化数据
  • 扩大艰难

罕用的 SQL 数据库比方 Oracle、MySQL、PostgreSQL、SQLite

NoSQL 泛指非关系型数据库
  • 表构造较灵便,比方列存储,键值对存储,文档存储,图形存储
  • 反对非结构化数据
  • 有的不须要预约义数据类型,有的甚至不须要预约义表
  • 反对大数据量
  • 少数都反对分布式
  • 扩展性好
  • 根本查问能力,高并发能力比拟强 (因为采纳非结构化、分布式,并就义一致性、完整性、事务性等性能)
  • 对数据一致性要求比拟低
  • 通常不反对事务性,或是无限反对
  • 通常不反对完整性,简单业务场景反对较差
  • 通常不反对多表 Join,或是无限反对
  • 非 SQL 查询语言,或类 SQL 查询语言,但性能都比拟弱,有的甚至不反对批改删除数据
  • 不是很通用,技术多样,市场变动比拟大
罕用的 NoSQL 数据库比方
  • 列式:HBase、Cassandra、ClickHouse
  • 键值:Redis、Memcached
  • 文档:MongoDB
  • 时序:InfluxDB、Prometheus
  • 搜寻:Elasticsearch

SQL 和 NoSQL 是一个互补的关系,利用在不同的场景中。

OLTP & OLAP

OLTP (On-Line Transaction Processing)
  • 次要做实时事务处理
  • 比方解决用户根本信息、解决订单合同、解决银行转账业务、企业的 ERP 零碎和 OA 零碎,等等
  • 频繁地,对大量数据,甚至是单条数据,做实时的增删改查
  • 数据库常常更新
  • 通常对规范化、实时性、稳定性、事务性、一致性、完整性等有要求
  • 操作较为固定,比方订单业务,可能永远就那几个固定的操作
  • 数据库次要模型是 3NF 或 BCNF 模型

OLAP (On-Line Analytical Processing)

  • 数据仓库,次要做历史数据分析,为商业决策提供反对
  • 比方对大量的用户行为做剖析,对设施的状态、使用率、性能做剖析
  • 频率较低地,对大量数据,做读取、聚合、计算、剖析,实时性要求不高,对吞吐能力要求较高
  • 通常列的数量比拟多,但每次剖析的时候只取少部分列的数据
  • 通常是批量导入数据
  • 通常数据导入后不会批改,次要是读取操作,写少读多
  • 通常对规范化、事务性、一致性、完整性等要求较低,甚至一个查问操作失败了也不会有什么影响
  • 操作较为灵便,比方一个海量用户行为数据表,能够想出许多不同的办法,从不同的角度对用户做剖析
  • 数据库次要是星型、雪花模型
  • 不应用高性能的 OLAP 之前,更传统的做法是通过离线业务构建 T+1 的离线数据,比拟滞后

OLTP 通常用传统的关系数据库,如果数据量大要分表,对事务性、一致性、完整性等要求不高的话也能够用 NoSQL

OLAP 通常用 NoSQL,数据量不大的话也能够用传统的关系数据库

关系型数据库 Oracle、SQL Server、MySQL、PostgreSQL、SQLite

Oracle:甲骨文开发的商业数据库,不开源,反对所有支流平台,性能好,性能强,稳定性好,安全性好,反对大数据量,比较复杂,免费低廉。

SQL Server:微软开发的商业数据库,只能在 Windows 运行。

MySQL:甲骨文领有的开源数据库,反对多种操作系统,体积小,性能弱些,简略的操作性能好,简单的操作性能差些。** PostgreSQL**:应用 BSD 协定的齐全开源收费的我的项目,反对多种操作系统,性能更弱小,能够和多种开源工具配合。

SQLite:开源、轻型、无服务器、零配置,一个数据库就只是一个文件,在应用程序内执行操作,占用资源小,可用于嵌入式或小型利用。

利用场景

Oracle 多用于银行等高要求的畛域,要求不高的比方互联网行业多用 MySQL 和 PostgreSQL,而 SQLite 用于嵌入式或作为应用程序内的数据库应用,SQL Server 用于 Window 服务器。

HBase (宽表、列式存储、键值对存储、NoSQL、OLTP)

  • 基于 Hadoop 的 HDFS 分布式文件系统
  • 分布式数据库,须要 ZooKeeper 作为节点间的协调器
  • 反对宽表,反对非结构化数据,不须要预约义列和数据类型
  • 列式存储,每个 HFile 文件只存储一个列族的数据,一个列族能够有多个 HFile,而 HFile 外部按 Key-Value 格局存储,其中 Key 是 rowkey, column family, column, timestamp 的组合并且按 rowkey 在 HFile 中按序存储,而 value 就是 Column Cell 的值
  • 反对海量数据 (千亿级数据表)
  • 数据先写入内存,达到阀值再写入磁盘,性能好,占用内存大
  • 不反对 SQL,不反对 Join,有本人专用的语句,反对增删改查
  • 主动分区、负载平衡、可线性扩大
  • 主动故障迁徙
  • 强一致性 (每个分区 Region 只由一个 Region Server 负责,容易实现强一致性)
  • CP 模型 (不保障可用性,每个 Region 只由一个 Region Server 负责,Server 挂了得做迁徙导致临时不可用)
  • 不反对事务、二级索引
利用场景

组件比拟多,比拟重,实用于已有的 Hadoop 平台,实用于海量宽表数据、须要增删改查、OLTP 的场景

Phoenix (基于 HBase 的数据库引擎、关系型、OLTP)

  • 嵌入到 HBase 的 Region Server 的数据库引擎
  • 反对 SQL
  • 反对 Join
  • 反对事务 (须要在定义表的时候配置)
  • 反对二级索引
  • 反对撒盐
  • 反对 JDBC
利用场景

用于强化 HBase,次要作为 OLTP,查问性能要求不高的话也可作为 OLAP,多用于 HDP (HDP 有集成 Phoenix)

Cassandra (宽表、键值对存储、NoSQL、OLTP)

  • 无单点故障:Cassandra 节点按环形排列,没有核心节点,每个节点独立互联地表演雷同角色,每个节点都能够承受读写申请,数据能够有多个正本存储在多个节点,节点之间通过 Gossip (P2P) 协定替换状态信息,集群中有若干节点配为种子节点,用于新退出的节点获取集群拓扑构造并启动 Gossip 协定
  • 提供类 SQL 语言 CQL
  • 适宜结构化、非结构化数据
  • Table 须要定义 Partition Key、Clustering Key、以及一般列,其中 Partition Key 用于分区和排序,即依照 Partition Key 的 Hash Token 决定了数据被调配到哪个节点,并且在节点内也是按该 Hash Token 按序存储的,有雷同 Partition Key 的数据会存在一起,并且依照 Clustering Key 排序存储,有点相似于 HBase 的 RowKey、ColumnFamily、Column,不过 HBase 是雷同 CF 存一起,外部再按 RowKey 排序存储,再取 Column 值 (Column 值不排序),而 Cassandra 是先按 Partition Key 的 Token 排序存储,外部再按 Clustering 排序存储,再取一般 Column 的值 (Column 值不排序)
  • 高度可扩大,容许增加硬件、节点以进步数据容量,同时放弃疾速的响应工夫
  • 通过 Consistency 命令能够配置一致性级别,次要是告诉客户端操作前,必须确保的 replica 的胜利数量
  • Cassandra 采纳的是最终一致性,是 CAP 实践里的 AP
  • Cassandra 不反对 Join 和子查问
利用场景

次要用于 OLTP,要求不高的话也能够作为 OLAP 应用,和 HBase 比须要的组件比拟少,保护比拟容易

Redis (基于内存的 Key-Value 的 NoSQL 数据库,OLTP)

  • 由 C 语言编写
  • 反对多种数据类型如 strings,hashes,lists,sets,sorted sets,bitmaps,hyperloglogs,geospatial 等
  • 操作原子性,保障了两个客户端同时拜访服务器将取得更新后的值
  • 数据存储在内存中
  • 能够配置长久化,周期性的把更新数据写入磁盘,或周期性地把批改操作写入追加记录文件,也能够敞开长久化性能,将 Redis 作为一个高效的网络缓存数据性能应用
  • 反对主从同步,数据能够从主服务器向任意数量的从服务器同步,从服务器能够是关联其余从服务器的主服务器,这使得 Redis 可执行单层树复制,存盘能够有意无意的对数据进行写操作,因为齐全实现了公布 / 订阅机制,使得从数据库在任何中央同步树时,可订阅一个频道并接管主服务器残缺的音讯公布记录,同步对读取操作的可扩展性和数据冗余很有帮忙
  • 反对音讯的公布 / 订阅(Pub/Sub)模式
  • 单线程模式,即网络 IO、数据读写,都由一个线程实现,正因为如此保障了原子性、稳定性、代码容易保护,之所以单线程不影响性能,是因为数据都在内存,操作原本就高效,当然这里的单线程指网络 IO、数据读写这个主性能,实际上还有其余线程,比方周期性写入硬盘的线程
  • 高版本在网络 IO 这块应用了多线程 (因为在高并发操作时,网络 IO 成为了瓶颈),但读写操作还是单线程 (操作内存数据性能还是十分高的,能应酬高并发场景)
利用场景

通常作为高性能内存数据库、缓存、消息中间件等应用

memcached (基于内存的 Key-Value 的 NoSQL 数据库,OLTP)

  • 开源、高性能、分布式的基于内存的 Key-Value 数据存储,作用相似于 Redis
  • 存储 String/RawData,不定义数据结构 (Redis 有 hash、list、set 等多种构造)
  • 数据通常由 key,flags,expire time,bytes,value 组成
  • 服务端基本上只能简略的读写数据,服务端能反对的操作比拟少
  • 蕴含 Server 组件和 Client 组件,能够有多个 server 但 server 之间是独立的,没有同步播送等机制,须要抉择哪个 server 由 client 的 API 决定的
  • 数据只在内存,不会落到硬盘
  • 没有平安机制
  • 协定简略性能高效
利用场景

memcached 比较简单,作为纯正的 Key-Value 缓存性能会比 Redis 好些,但性能没有 Redis 弱小

MongoDB (文档数据库,NoSQL,OLTP)

之所以说是文档数据库,是因为它的数据是以 JSON 文档的模式存储

MongoDB 的概念和很多数据库不一样,它的 collection 相当于表,document 相当于行,field 相当于列,比方:

db.user.insert(
    {
        "name": "Lin",
        "age": 30
        "address": {
            "street": "Zhongshan Road",
            "city": "Guangzhou",
            "zip": 510000
        },
        "hobbies": ["surfing", "coding"]
    }
)

这是一条插入语句,这里的 db 是指以后数据库,user 就是 collection 相当于表,insert 语句外面的 JSON 就是 document 相当于其余数据库的行,name,age,street 这些就是 field 相当于列

雷同的文档能够插入屡次而不会被笼罩,实际上 mongodb 会主动创立 \_id 字段作为 primary key,并调配不同的数值,所以不会反复,也能够 insert 的时候指定 \_id,但如果 \_id 曾经存在则会报错

  • 能够看到,mongodb 是非结构化数据,不须要预约义 collection,也不须要预约义数据结构
  • 提供丰盛的查问表达式
  • 反对二级索引,主动负载平衡,读效率比写高
  • 反对分布式、反对故障复原、数据冗余、分片、程度扩大
  • 能够配置存储引擎,WiredTiger Storage Engine (默认) 会做内存到文件的映射以进步性能,但内存耗费大,In-Memory Storage Engine (企业版反对) 只存在内存,不会落盘
  • 高版本反对 Join,反对事务
  • 反对平安认证性能
  • 提供扩大,比方实现可视化的工具,实现 BI 集成的工具
利用场景

mongodb 更实用于高度非结构化,或者源数据就是 JSON,每条数据比拟大,以 OLTP 为主的场景,不适宜于事务要求比拟高,或比较复杂的大数据量的查问的场景,另外因为 mongodb 的语法和其余数据库差别比拟大,须要肯定的学习老本

Hive (基于 HDFS 的数据库引擎、关系型、OLAP)

  • Hive 是基于 Hadoop 的一个数据仓库工具
  • 数据存储在 HDFS,创立表的时候要通过 STORED AS 命令指定存储格局比方 TEXTFILE、ORCFILE、PARQUET,也能够通过 STORED BY 命令指定为 HBase,能够创立新表也能够创立已有 HBase 表的映射
  • 查问通过 MapReduce、Spark 等作业实现
  • 提供了类 SQL 查询语言 HQL (HiveQL),反对用户定义函数 (UDF)
  • 高版本反对事务 (须要创立表时指定)
  • 反对海量数据
  • 结构化数据
  • 反对增删改查
利用场景
  • 不适宜于 OLTP,次要作为 OLAP 用于大数据批量查问应用,须要有 Hadoop 平台

Impala (基于 HDFS、HBase、Kudu 存储,并行计算,关系型,OLAP)

  • Cloudera 开发的基于内存的分布式并行计算的数据库查问引擎
  • 次要由 C++ 实现,和 Hadoop 的交互应用 JNI
  • Impala 应用和 Hive 一样的 metadata、SQL、ODBC driver、UI,这样在进步了 HDFS 的 SQL 查问性能的同时,又提供了类似的用户应用体验
  • 和 Hive 一样能够通过 STORED AS 指定 HDFS 的存储格局比方 TEXTFILE、ORCFILE、PARQUET
  • 通过 Hive 操作的表,须要手动同步到 Impala
  • Impala 不仅 SQL 和 Hive 一样,实际上元数据也存在 Hive 中
  • 表数据除了 HDFS,也能够存储到 HBase,但须要在 HBase 建表,而后在 Hive 通过 STORED BY 建设映射表,因为 Impala 和 Hive 应用一样的 metadata,在 Hive 建好表后,只有在 Impala 执行刷新命令 INVALIDATE METADATA,就能够看到对应的 HBase 表
  • 反对 Join、Aggregate 等性能
  • 反对 JDBC、ODBC
  • 和 Hive 不同,Impala 不依赖于 MapReduce,而是在每个 HDFS DataNode 上运行本人的引擎实现并行处理
  • Impala 的并行处理引擎次要由 state store、catalog service、多个 impala daemon 组成
  • 每个 impala daemon 都能够接管 client 的申请,impala daemon 由 query planner、query coordinator、query executor 组成,planner 接管 client 的 SQL 查问,而后合成为多个子查问,由 coordinator 将子查问散发到各个 daemon 的 executor 执行,daemon 获取 HDFS、HBase 数据、计算、而后返回给 coordinator,而后由 coordinator 聚合后将最终后果返回给 client
  • Impala 是无核心构造,每个 daemon 都能够承受连贯查问,能够通过 HA Proxy 实现多个 daemon 的负载平衡
  • state store 用于收集监控各个 daemon 的状态
  • catalog service 将 SQL 做出的元数据变动告诉给集群中所有的 impala daemon
  • Impala 的计算都在内存进行,对内存要求比拟高
  • Impala 在 2.8 当前才反对 update 操作,然而只限于 Kudu 存储,须要装置 Kudu,并通过 STORED AS 指定 Kudu 作为数据库的存储,Kudu 是 Cloudera 开发的列式存储管理器,目标是做 OLAP,并且均衡 HDFS 和 HBase 的性能,Kude 的随机读写性能比 HDFS(比方 Parquet)好,然而比 HBase 差,而大数据量查问性能比 HDFS(比方 Parquet)差,但比 HBase 好,Kude 和 Impala 高度集成,也能够和 MapReduce/Spark 集成,用 Kudu 替换 HDFS/HBase 这样 Impala 就能够做 update,兼顾 OLAP 和改数据的需要,适宜于以 OLAP 为主又有肯定的 Update 需要的场景,Kudu 能够配置一致性,采纳结构化表数据模型,须要定义主键,不应用 HDFS 而是有本人的组件存储和治理数据, 采纳 c++ 没有 full gc 危险
利用场景
  • Impala 不适宜于 OLTP,次要作为 OLAP 用于大数据批量查问应用
  • 须要有 Hadoop 平台和 Hive
  • 性能比 Hive 好很多
  • 作为 OLAP 的性能比 Phoenix 之类的好
  • 次要是 CDH 在推,CDH 有集成 Impala

Presto (基于多种数据源,并行计算,关系型,OLAP)

  • Facebook 推出的基于内存的分布式并行计算的数据库查问引擎
  • 由 coordinator server、discovery server (通常集成在 coordinator 里,也能够独立)、多个 worker server 组成
  • coordinator 负责与 client 交互,负责管理 worker,负责解析 statement、布局 query、创立一系列的 stage、再转换成一系列的 task 散发到不同 worker 并发执行
  • worker 负责执行 task 和解决数据,会通过 connector 获取数据,和其余 worker 交互两头数据,最终后果会由 coordinator 返回给 client
  • connector 是适配器,使得 Presto 能够拜访不同的数据库
  • 内建的 connector 次要是 Hive,此外有很多三方开发的 connector 比方 cassandra、es、kafka、kudu、redis、mysql、postgresql 等等
  • 须要在配置文件配置 catalog,这里 catalog 保护 schema 并通过 connector 指向一个数据源,定位 presto 表都是从 catalog 开始的,比方 hive.test\_data.test 指的是 hive catalog 下的 test\_data schema 上面的 test 表,而 schema 的概念则依赖于具体的 connector,比方对于 mysql 而言,presto 的 schema 就是 mysql 的 schema,而对于 cassandra 而言,presto 的 schema 就是 cassandra 的 keyspace,能够建设多个 catalog 关联同一个 connector 比方环境里有多个 kafka 集群那能够有 kafka1 和 kafka2 两个 catalog
  • statement 能够认为就是 presto 收到的 sql 语句,而后会解析成 query plan,而后 query 又被分为多个 stages,这些 stages 组成一个树的构造,每个 stage 会聚合计算它上面的其余 stages 的后果,每个 stage 又分为一个或多个 tasks,这些 task 会散发到不同的 worker 并行执行,每个 task 解决不同的数据分片,每个 task 又有一个或多个 driver 并发解决数据
  • Presto 反对 JDBC 接口,JDBC 的 URL 格局为 jdbc:presto://host:port/catalog/schema 或 jdbc:presto://host:port/catalog 或 jdbc:presto://host:port
  • 反对 Join 查问,并且反对多数据源的 join 查问 (多张大表的 join 可能会影响性能),跨数据源查问的时候须要指定残缺的表名即 [catalog].[schema].[table],并且应用 presto://host:port 连贯 JDBC,不指定 catalog 和 schema
  • 无限反对子查问
  • 不反对 update 操作
  • 反对平安机制
  • 反对规范的 ANSI SQL
  • 扩展性好
  • 能够和 Tableau 集成
  • 反对 Spark
利用场景
  • 适宜有多种数据源的大数据量的 OLAP 查问
  • 性能和 Impala 可能差不多,但反对多种数据源,不依赖 Hadoop

Greenplum (基于多个 PostgreSQL,并行计算,关系型,OLAP)

  • 基于多个 PostgreSQL 的分布式并行计算的数据库查问引擎
  • 外部的 PostgreSQL 有做改变以适应并行分布式计算
  • 次要由一个 master、多个 segments、一个 interconnect 组成
  • master 保护元数据,接管并认证 client 的链接,接管 SQL 申请,解析 SQL,生成 query plan,并将工作散发到 segments,协调聚合 segments 的返回后果,并将最终后果返回给 client,能够设置 master 为主从配置
  • 每个 segment 有个独立的 PostgreSQL 数据库,每个 segment 负责存储局部数据,并执行相应的查问计算,segment 也能够配置备份机制
  • Interconnect 是 Greenplum 的网络层,负责 master 和 segment 的链接,以及各个 segment 之间的链接
  • 链接和 SQL 语法都和 PostgreSQL 兼容,反对 JDBC、ODBC
  • 创立表时能够指定是用列存储、行存储、内部表 (数据在其余零碎比方 HDFS 而 GP 只存储元数据)
  • 操作内部数据,须要装置 PXF (Platform Extension Framework),有了 PXF 能够反对 Hive、HBase、Parquet、S3、MySQL、ORACLE 等等
  • 反对平安、权限配置
  • 反对分布式事务,反对 ACID,保证数据的强一致性,不是应用锁,而是应用 MVCC (Multi-Version Concurrency Control) 来保证数据一致性
  • shared-nothing 架构
利用场景

和 Impala、Presto 相似都是并行内存计算,但 Greenplum 性能可能稍差一点点,并且 Greenplum 还离开源版和商业版,有的性能只有商业版才反对

Kylin (基于 Hive、HBase,并行计算,关系型,多维度、预计算 OLAP)

传统 OLAP 依据数据存储形式的不同分为 ROLAP(Relational OLAP)以及 MOLAP(Multi-Dimension OLAP),ROLAP 以关系模型的形式存储数据,长处在于体积小,查问形式灵便,毛病是每次查问都须要对数据进行聚合计算,而 Kylin 属于 MOLAP

Kylin 将数据按维度的不同组合,提前计算好后果,造成 Cube (立方体) 构造,这样查问速度快,毛病是数据量不容易管制,N 个维度能够有 2**N 种组合,可能会呈现维度爆炸的问题,而且数据有改变的话须要从新计算

比方有 Phone 和 Country 两张维度表,以及 Sale 事实表 (明细表),取手机品牌、国家、日期作为三个维度,有 (null)、(品牌)、(国家)、(日期)、(品牌、国家)、(品牌、日期)、(国家、日期)、(品牌、国家、日期) 共 8 种组合,能够提前计算好这 8 种 group by 组合的 sale 的各种汇总信息 (sum、count 等),一个维度组合的一个汇总信息称为一个 cuboid,所有的 cuboid 合起来就被称为一个 Cube

Kylin 的数据源能够是 Hive 或 Kafka (Json 格局音讯,key 就是列名)

Kylin 的预计算后果存到 HBase,RowKey 就是各种维度的组合,相应的明细汇总存在 Column 中,这样 SQL 就变成对 RowKey 的扫描,并进一步的对 Column 计算 (如果需要的话),这样查问性能天然就晋升了,能够反对亚秒级查问

Kylin 反对 ODBC,JDBC,RESTful API 等接口

Kylin 能够和 Tableau、PowerBI 等 BI 工具集成

应用步骤如下
  • 创立 Project
  • 同步 Hive 表或 Kafka 表
  • 创立 Data Model
  • 创立并命名 Model
  • 抉择 Fact Table (事实表) 和 Lookup Table (查找表,次要是维度信息),以及 Join 字段
  • 从 Fact Table 和 Lookup Table 中筛选维度列 (能够被 Cube 做 group by)
  • 从 Fact Table 抉择指标列 (能够被 Cube 做 aggregation)
  • 从 Fact Table 抉择用于日期分区的列,不须要就留空
  • 增加 Filter (能够被 Cube 用来做 Where 操作)
  • 创立 Cube
  • 创立并命名 Cube,并抉择要关联的 Data Model
  • 增加维度列 (必须从 Data Model 配置的维度列中抉择)
  • 增加指标列 (必须从 Data Model 配置的指标列中抉择)
  • 共有 8 种 aggregation 操作能够配置给指标列:SUM, MAX, MIN, COUNT, COUNT\_DISTINCT, TOP\_N, EXTENDED\_COLUMN and PERCENTILE (如果要查 avg 实际上就是用 sum 除以 count 得出,所以这里不须要配置 avg 等能够通过预计算后果进一步计算出的操作)

build Cube,理论是通过 MapReduce/Spark 计算,工作实现后后果会写入 HBase

build 胜利后即可间接用 SQL 查问了,理论是依据维度查 RowKey,而后把 Column 存的聚合后果取出,如果必要的话再做进一步计算

如果数据源有改变,须要从新 build Cube

能够看到 Kylin 是一个纯正的 OLAP 工具,通过预计算晋升查问性能,但无奈及时反馈出数据源的扭转,预计算可能很耗时并且可能会占用大量空间,且须要和 Hadoop 集成

基于预计算的 OLAP 数据查问引擎还有 Druid

ClickHouse (列存储,向量化计算,并行计算,OLAP)

俄罗斯企业 Yandex 开发的 OLAP 数据库

  • 列存储对于 OLAP 的益处
  • 因为 OLAP 常常是在大量数据列中检索少量列,如果采纳行存储,意味着要逐行扫描,并且每行都很大,而采纳列存储只须要扫描要检索的列,能缩小 IO
  • 假如有的记录并没有存储要检索的列,行存储仍然要扫描该记录才晓得,而对于列存储则不存在这样的问题,因为没存储,自热而然就不会扫描到
  • 因为同一列的数据类型、大小比拟统一,列存储更容易压缩,效率更高,进一步缩小 IO
  • IO 的缩小还意味着有更多数据能够被缓存到内存
  • 向量化计算
  • SIMD (Single Instruction,Multiple Data,单指令流多数据流),当初的 CPU 反对这样的性能,通过一条指令即可利用多核查一组数据 (也就是向量) 进行 CPU 层面的并发计算,实用于纯根底计算的场景,如果有判断、跳转、分支的场景则不适合
  • ClickHouse 有一个向量计算引擎,尽可能地应用 SMID 指令,批量并行地解决数据,大大晋升了解决能力
  • 次要由 C++ 实现
  • 无中心化构造,由一个集群的 server 组成,并且每个 server 都能够承受客户端的链接查问,server 收到申请后会和其余 server 协调做并行计算,每个 server 都是多线程的,server 之间通过 ZooKeeper 协调同步
  • 反对分片(shard),数据能够跨节点存储在不同分片中,一个分片就是一个节点,或者多个节点组成一个有正本备份的分片,由配置文件配置
  • 反对分区,通过 Partition By 命令创立表
  • 分片和分区有时候不好辨别,分片更多指的是表的数据分布在不同节点,而且一个节点能够存储多个数据库、多个表的数据,而分区更多指的是按某列数据将一个大表分成多个小表,比方按日期列分区,每天一个分区表,既能够查分区表,也能够查大表
  • 反对正本备份、反对数据完整性
  • 表引擎(Table Engine)
  • 在某个 server 创立的表只是该 server 的本地表,不是分布式的,如果要创立分布式表,须要在每个 server 创立雷同名字的表,再在其中一台 server 上创立分布式表(会主动在所有 server 上都创立),这个分布式表是个逻辑表,不真正存储数据,而是映射到各个 server 的本地表,会主动做并行计算
  • ENGINE = Distributed(cluster\_name, database, table, [sharding\_key])
  • cluster\_name 是在配置文件里配置的
  • ENGINE = Memory 数据存在内存
  • ENGINE = ODBC(connection\_settings, external\_database, external\_table)
  • ENGINE = JDBC(dbms\_uri, external\_database, external\_table)
  • ENGINE = MySQL(‘host:port’, ‘database’, ‘table’, ‘user’, ‘password’)
  • ENGINE = PostgreSQL(‘host:port’, ‘database’, ‘table’, ‘user’, ‘password’)
  • ENGINE = MongoDB(host:port, database, collection, user, password)
  • ENGINE = HDFS(URI, format)
  • ENGINE = Kafka() SETTINGS kafka\_broker\_list = ‘host:port’, kafka\_topic\_list = ‘topic1’
  • ENGINE = Log;
  • ENGINE = TinyLog;
  • ENGINE = MergeTree()
  • ENGINE = AggregatingMergeTree()
  • 创立表的时候要通过 Engine 命令指定要用的表引擎,决定如何存储数据
  • 最罕用的是 MergeTree 系列引擎,比方
  • 比拟轻量级的 Log 系列引擎
  • 容许从其余数据源查问,比方
  • 非凡类型,比方
  • 分布式
  • 通常应用 MergeTree 存储,数据能够疾速地按序 append 到一颗 MergeTree 的前面,后盾会做合并和压缩操作,这样晋升了数据插入的性能
  • 主索引,数据按 Primary Key 排序
  • 也能够在创立表时通过 Order By 指定排序的字段
  • 反对二级索引,也叫跳数索引 data skipping index,比方 minmax 索引,会统计每一段数据内某列数据(或是某个表达式)的最大值和最小值,检索的时候能够根据 minmax 决定是否跳过这段数据(感觉比拟怪,性能应该比重建一张索引表的做法要差吧)
  • 反对 TTL,包含列级别、行级别、分区级别的 TTL
  • 反对 HTTP、TCP 接口
  • 反对 JDBC、ODBC
  • 有三方工具反对将其余数据库如 PG 的数据导入 ClickHouse
  • 有三方工具反对和一些可视化工具如 Grafana、DBeaver、Tabix 集成
  • 有三方工具反对 Kafka、Flink、Spark 等
  • 反对 SQL,反对 group by、order by、join、局部子查问等性能
  • 反对 array、json、tuple、set 等简单数据类型
  • 反对近似计算,比方计算平均值,能够取局部数据计算,这样晋升了性能,但升高了准度
  • 自适应 Join 算法,比方优先应用 Hash-Join,如果有多张大表则主动改用 Merge-Join
  • 平安机制、基于 Role 的权限管制
  • 反对谬误复原、扩展性好
有余的中央
  • 对高并发的反对有余
  • 没有成熟的事务性能
  • 批改、删除数据的性能比拟差,并且仅提供无限反对
  • Primary Key 是采纳稠密索引,即索引只能指向一段数据,具体的数据还得一条条查,所以如果是查大量数据,或者查问单条数据,性能会比拟差

不依赖 Hadoop、列存储、向量化、并行、多线程、多存储引擎

单表查问性能极好,比 Impala、Presto 之类的要好很多

多表查问性能差些,比 Impala、Presto 之类的要差

Elasticsearch (倒索引、分词、搜索引擎)

  • Elastic Stack 是一组组件包含 Elasticsearch、Logstash、Filebeat、Kibana 等
  • Elasticsearch 是基于 Apache Lucene 开发的搜索引擎,次要由 Java 开发
  • Elasticsearch 集群次要由 master、data、ingest、coordinating 节点组成
  • 每个节点能够同时配置多种角色,比方即是 master 又是 data,但在大型集群中,通常每个节点只累赘一种性能
  • coordinating 是每个节点都会有的性能,不须要配置,即无论 master 还是 data 都会有 coordinating 性能,用于接管 client 的读写申请,而后将申请转发给相应节点解决,而后将处理结果合并后返回给 client,在大型集群中为了不对 master/data 等节点造成太大压力,能够配置多个专门的 coordinating,通过将 role 配置为空或是将 master、data、ingest 设置为 false (取决于不同版本) 即可,这样这些 coordinating 节点就只负责接管响应 client 申请不做其余工作,就像是一个反向代理的负载平衡一样,能进步并发性能
  • master 负责管理整个集群,负责对 index 的创立删除等治理操作,决定数据要分片到哪个节点,治理其余节点的状态等等,能够配置多个 master 做 HA,须要复数个,至多要 3 个,零碎实际上主动选举其中一个做 master,如果该 master 挂了,会从其余配置为 master 的节点中从新选举一个,master 的配置能够低一些
  • data 负责存储、计算、解决数据,对资源要求比拟高,data 还能够进一步配置,指定节点用于存储 hot data、warm data、cold data 等等
  • Ingest 是可选节点,专门用于针对某些数据和操作,做流水线预处理
  • Elasticsearch 的数据存储次要由 index,type,document 组成
  • index 就相似于 SQL 中的一个数据库,能够间接创立 index,也能够通过 index template 作为模板创立 index,模板通常用于具备雷同配置的多个 index,比方每天都建设一个 index 用于存储当天的日志
  • type 就相似于 SQL 中的表 (这种说法不齐全对,官网有廓清过,因为不同的 type 并不是齐全独立无关的),晚期版本中,一个 index 下能够有多个 type,从 6.0 开始只能有一个 type,从 7.0 开不倡议应用 type 这个概念,据说从 8.0 开始将齐全不反对 type
  • document 就是像是 SQL 中的一行记录,document 应用的是非结构化的数据,由 JSON 格局示意,JSON 的每个 field 就相当于一个列
  • 每个 document 会一个惟一的 \_id,如果不指定则由零碎主动生成
  • 每个 document 有严格递增的序号 \_seq\_no 代表文档写入 / 更新的先后顺序
  • 每个 document 有 \_version 字段,每次更改这个字段就加 1
  • 能够先建设 index,也能够不提前建设 index,写入数据时主动创立
  • 不须要提前设置 document 的 field,写入数据时主动创立,每个 document 的 field 能够不一样,也能够提前设置 field,使得每个 document 的 field 必须一样
  • Elasticsearch 会主动对所有 field 建设索引,并且会主动做分词解决,即把一个句子比方 “hello world” 主动分成 “hello” 和 “world” 两个词做索引,没有分词的 “hello world” 是 keyword,大小限度是 256,通过分词的比方 “hello” 是一个 text
  • Elasticsearch 采纳倒索引 (inverted index),次要由三局部组成:Term Index (单词索引)、Term Dictionary (单词字典)、Posting List (索引项列表)
  • Term Index 存在内存中,不保留所有单词,而是保留单词的前缀,比方保留 he、wor、ad、sar 等等,指出以这些前缀作为结尾的单词在 Term Dictionary 中的起始地位,这样 Term Index 的大小就比拟小,能够存在内存中,并且能够帮忙疾速定位要读取的内容在 Term Dictionary 中的地位,能够大大减少磁盘 IO 的次数
  • Term Dictionary 存在磁盘中,通常单词量会十分大,记录着 index 的每个单词到 Posting List 的关联关系,通过 B+ 树或 Hash 表形式以满足高性能的插入与查问
  • Posting List 记录着:呈现该单词的所有 document 的 id,该单词在该 document 中呈现的次数,该单词在该 document 中的地位
  • 搜索引擎通过这样的倒排序索引找到对应的 document,再做进一步解决
  • 因为会对所有 field 做索引,数据量会十分大
  • 数据先写入内存,而后定期将数据落盘造成一个个 segment,当 segment 多了之后会进行 merge 组成更大的 segment
  • 为了避免内存中还败落盘的数据失落,会写入 translog,相似于 HBase 的 WAL,其实这也须要磁盘 IO,会影响性能,但比落盘数据要简略
  • segment 由多个文件组成,记录着元数据、field 信息、正排序的索引信息 (即从 document id 找到相应的数据)、field 数据 (相当于按列存储)、倒排序索引数据、等等
  • 反对 REST API 接口操作,通过在 Body 的 JSON 格局数据进步丰盛的语法,能够执行很多操作
  • 反对 Event Query Language (EQL):for event-based time series data, such as logs, metrics, and traces, 通过 REST API 的 Body 指定
  • 反对 JDBC、ODBC,这里 table 指定的是 index,而 column 指定的是 field,这里的 SQL 不反对 JOIN
  • 不反对事务
  • 跨表查问不齐全反对,而且要定义父子文档,要定义 join 类型的 field,比较复杂
  • 读写有肯定延时性,即写入的数据无奈立即索引到,至多要等 1 秒钟
  • 和传统的数据库有肯定差别,须要肯定的学习老本
局部 REST API 操作的例子
curl localhost:9200                          # 查看集群根本信息
curl localhost:9200/_cluster/health?pretty   # 查看集群衰弱 (pretty 是 JSON 格式化输入)
curl localhost:9200/_cluster/state?pretty    # 查看集群状态
curl localhost:9200/_cluster/stats?pretty    # 查看统计信息
curl localhost:9200/_nodes?pretty            # 查看节点信息

curl localhost:9200/_cat                     # 列出能够查看的各种信息 (cat 命令列出的信息比拟简化)
curl localhost:9200/_cat/health
curl localhost:9200/_cat/nodes
curl localhost:9200/_cat/indices

curl -X PUT 'http://localhost:9200/my_index/my_doc/123'  -H 'Content-Type: application/json' -d '{"name":"Lin","title":"senior designer","age": 30}'      ## 指定 document id 为 123,会主动创立 my_index,my_doc 以及各个 fields

curl -X POST 'http://localhost:9200/my_index/my_doc'  -H 'Content-Type: application/json' -d '{"name":"Wang","title":"senior designer","age": 35}'      ## 由零碎主动创立 document id

curl -X POST 'http://localhost:9200/my_index/my_doc_2'  -H 'Content-Type: application/json' -d '{"name":"n_1","type":"t_1","value": 1}'      ## 报错,不容许 index 下有两个 type

curl -X POST 'http://localhost:9200/my_index/_doc'  -H 'Content-Type: application/json' -d '{"name":"n_1","type":"t_1","value": 1}'      ## 容许,_doc 就是 my_doc(能够一开始就只用 _doc 而不须要 type 名)curl -X POST 'http://localhost:9200/my_index/_doc'  -H 'Content-Type: application/json' -d '{"name":"Li","address": {"city":"guangzhou","district":"tianhe"}
}'## 容许新的 fields,容许简单类型,貌似不反对列表"address": ["xxx"]

curl localhost:9200/my_index/my_doc/123?pretty        ## 查看 id 为 123 的记录
curl localhost:9200/my_index/my_doc/_search?pretty    ## 查看所有记录
curl localhost:9200/my_index/_search?pretty

curl localhost:9200/_all?pretty                   ## 列出所有 index 的设置和 mapping (就是 field 的信息)
curl localhost:9200/my_index?pretty               ## 查看 my_index 的设置和 mapping
curl localhost:9200/my_index/_mapping?pretty      ## 查看 my_index 的 mapping

curl -X GET -H "Content-Type: application/json"  localhost:9200/my_index/_search?pretty -d '{"query": {"term":{"name":"lin"}
   }
}'        ## 简略的查问,还有更多的语法和性能

curl -X GET -H "Content-Type: application/json"  localhost:9200/my_index/_search?pretty -d '{"query": {"term":{"title.keyword":"senior designer"}
   }
}'        ## 默认查问的是分词,如果要查没分词的,应该加上 keyword

curl -X GET -H "Content-Type: application/json"  localhost:9200/my_index/_search?pretty -d '{"query": {"term":{"address.city":"guangzhou"}
   }
}'        ## 查问嵌套的字段

curl localhost:9200/_search?pretty        ## 在所有 index 中查找

curl -H "Content-Type: application/json" localhost:9200/my_index/_analyze?pretty -d '{"analyzer":"standard","text":"This is the apple"}'        ## 如何剖析一段文字

curl -X PUT 'http://localhost:9200/my_index_3'    ## 创立 index

curl -X PUT -H "Content-Type: application/json" 'http://localhost:9200/my_index_6' -d  '{"settings": {"number_of_shards": 1,"number_of_replicas": 1},
    "mappings": {
        "properties": {
            "name": {"type": "text"},
            "title": {"type": "text"},
            "value": {"type": "long"}
        }
    }
}'         ## 创立 index 同时指定 field,在版本 7 当前不须要指定 type (不须要指定 my_doc 之类的)
利用场景

适宜于以搜寻为主的业务场景,最开始 ELK (Elasticsearch + Logstash + Kibana) 就是用于日志收集和搜寻

Spark/Flink

数据库尽管弱小,但如果遇到简单的逻辑计算也是无能为力,这种状况,就须要有专门的计算工具

Spark 和 Flink 都是高性能的并行计算引擎,Flink 更偏差实时流业务,Spark 更偏差批处理业务,都能够用来高效地解决数据

BI

数据通常要可视化,比拟罕用的 BI 工具有 Tableau (免费的) 和 PowerBI

整体零碎架构

K8S (容器部署) + SpringCloud (微服务) + Keycloak (认证) + Kafka (数据流) + Spark/Flink (数据处理) + ELK (日志收集) + PG/MySQL (根本数据) + NoSQL-OLTP (大数据量业务数据) + OLAP (剖析业务) + BI (数据可视化)

正文完
 0