0%

推荐分析

业界常用场景 推荐场景 推荐分析 注意事项
redis 内存数据库、缓存、秒杀等高并发场景 1、需要支持高并发读写场景 主要特征依然是缓存数据,宕机存在短时间内的数据丢失,重要数据要先保证落库(mysql)
tair 一种基于ssd降本考虑的替代redis的方案 1、同样支持高并发读写场景 理论上性能是略低于redis的 1、实测除非对于rt要求近乎变态的场景,否则可选tair 2、暂时数据结构支持的有限(k/v结构)
Elasticsearch 1、日志查询 2、增强MySQL结构化查询 3、检索 4、比较小的聚合统计 1、全文检索 2、增强结构化查询的场景 1、近实时,写入后1s可见(默认) 2、统计聚合支持一般,数据量不能超过百万,聚合QPS支持不高 3、不支持事务 4、不支持联表,通过嵌套结构实现
Clickhouse 1、时序数据库 2、OLAP,海量数据统计聚合分析 1、监控 2、聚合分析 支持QPS不高
hbase 订单/账单存储、用户画像、时空/时序数据、对象存储、Cube分析、Feeds流等 1、大表及高并发场景 单表数据量超过千万或者十亿百亿的时候,并且伴有较高并发,可以考虑使用HBase 2、单条记录查询 Hbase对Rowkey做了索引优化,数据量庞大的情况下,根据行键的查询效率依然很高,非常适合根据行键做单条记录的查询 数据分析是HBase的弱项,如果主要的业务需求就是为了做数据分析,比如做报表,那么不建议直接使用HBase。
tidb 1 对数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高的金融行业属性的场景 2 对存储容量、可扩展性、并发要求较高的海量数据及高并发的 OLTP 场景 3 Real-time HTAP 场景(HTAP指oltp+olap) 4 数据汇聚、二次加工处理的场景 1、高并发海量数据的读写场景 1、分布式数据库对海量数据多个kv同时计算 2、集群扩展性很强 1、单条sql处理能力弱于mysql 2、tidb-server对大规模的聚合查询需求的内存比较高

基础特性

数据库 并发(读/写)参见存储选型标准测试报告 实时可见性 事务支持 高可用 并发一致性 动态扩缩 分片聚合查询 全文检索 存储结构 type 语法
mysql 取决于:表结构大小,以及表关联的复杂度等 实时: 需关注事务级别 ACID 主库和高可用备库是半同步,跟业务从库是异步 mvcc / / 差 行 关系型 sql
mysql sharding 依赖分片数 实时:需关注事务级别 默认本地事务 主库和高可用备库是半同步,跟业务从库是异步 mvcc / / 差 行 关系型 对sql的特殊预发支持有限
redis 高读写: (如果特殊场景要用uc的集群版本需注意:集群版本支持的qps跟内存的大小有关系:1g 3000qps) 实时 支持有限:不建议使用 高可用版本:1、异步同步 2、aof策略appendfsync=everysec 支持部分原子性操作 支持:纵向扩容(最大64g) / / kv/list/hash.. 内存数据库
Tair 高读写 实时 不支持 异步同步 支持:版本控制、原子性计数 支持:水平扩缩 / / k/v 基于ssdkv存储
Elasticsearch 单台 QPS:千级 TPS:千级 依赖机器数和shard数 近实时(1s可见) 不支持 同步写从:从必须写入成功 乐观锁 支持 支持:性能一般 聚合百万数据基本达到瓶颈,支持QPS较低 好 倒排索引 + 行 文档型 dsl
Clickhouse 查询:100左右 写入:速度大约为50MB/s(必须批量) 实时 不支持 高可用 / 分析性数据库:非常好 差 列
hbase 高读写 实时 支持 分布式高可用 使用行锁+MVCC机制实现一致性 支持:水平扩缩 支持 / 列 分布式数据库 Native Java API /Thrift Gateway/Rest Gateway
tidb 取决于:分布式集群的大小,并发性总体好于mysql(相对) 实时:但是简单sql的处理能力不好 ACID 分布式高可用 mvcc 支持 支持 / 行+列 关系型 sql

测试报告

存储 常规指标 性能测试报告
redis get/set:写:7w+/s;读:9w+/s
mysql 20张表,200万数据:tps:3000+;qps:50000+
tair get/put:写:1w+/s;读:3w+/s
Clickhouse 参见测试报告 https://clickhouse.tech/benchmark/dbms/
tidb 参见测试报告 https://docs.pingcap.com/zh/tidb/dev/benchmark-tidb-using-sysbench
Elasticsearch 参见测试报告

选型对比

ElasticSearch vs MongoDB

MongoDB ElasticSearch 备注
定位 (文档型)数据库 (文档型)搜索引擎 一个管理数据,一个检索数据 Elasticsearch更倾向于数据的查询, 一般情况下elasticsearch仅作为数据检索服务和数据分析平台, 不直接作为源数据管理者
资源占用 一般 高 mongo使用c++, es使用Java开发
写入延迟 低 高 es的写入延迟默认1s, 可配置, 但是要牺牲非常大的性能
全文索引支持度 一般 非常好 es本来就是搜索引擎, 这个没啥可比性
有无Schema 无 无 两者都是无Schema
支持的数据量 PB+ TB+ ~ PB 两者支持的量并不好说的太死, 都支持分片和横向扩展, 但是相对来说MongoDB的数据量支持要更大一点
性能 非常好 好 MongoDB在大部分场景性能比es强的多得多
索引结构 B树 LSM树 es追求写入吞吐量, MongoDB读写比较均衡
操作接口 TCP Restful(Http)
是否支持分片 是 是
是否支持副本 是 是
选主算法 Bully(霸凌) Bully(霸凌) 相比于Paxos和Raft算法实现更简单并有一定可靠性上的妥协,但是选举速度比较快
扩展难度 容易 非常容易 es是扩展最方便的存储系统之一
配置难度 难 非常容易
地理位置 支持 支持
运维工具 丰富 一般

Redis vs Tair

存储 同步 容量成本 性能 支持数据结构 场景
redis 主要内存,磁盘异步持久化数据 异步 强 kv/hash/list… 缓存/抗并发
tair 磁盘主要ssd,内存提供二级缓存(可选) 异步 稍微弱于redis 目前支持kv和前缀kv 可用于存储,提供多副本节点保证数据安全

MySQL vs TiDB

SQL语法 隔离级别 锁 存储过程/触发器/事件 外键约束 CREATE TABLE tblName AS SELECT CREATE TEMPORARY TABLE
mysql 全支持 支持读未提交、读已提交、可重复读、串行化,默认为可重复读 悲观锁 支持 支持 支持 支持
Tidb 兼容绝大多数 乐观事务支持快照隔离,悲观事务支持快照隔离和读已提交 乐观锁、悲观锁 不支持 忽略外键约束 不支持 TiDB 忽略TEMPORARY 关键字,按照普通表创建

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。本章系Java之美[从菜鸟到高手演变]系列之设计模式,我们会以理论与实践相结合的方式来进行本章的学习,希望广大程序爱好者,学好设计模式,做一个优秀的软件工程师!

阅读全文 »

斐波那契数列

有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

1.程序分析:这个是典型的斐波那契数列,兔子的规律为数列1,1,2,3,5,8,13,21….

具体分析如下:

f(1) = 1(第1个月有一对兔子)
f(2) = 1(第2个月还是一对兔子)
f(3) = 2(原来有一对兔子,第3个开始,每个月生一对兔子)
f(4) = 3(原来有两对兔子,有一对可以生育)
f(5) = 5(原来有3对兔子,第3个月出生的那对兔子也可以生育了,那么现在有两对兔子可以生育)
f(6) = 8(原来有5对兔子,第4个月出生的那对兔子也可以生育了,那么现在有3对兔子可以生育)
…………..
由以上可以看出,第n个月兔子的对数为
f(n) = f(n - 1) + f(n - 2);
f(n-1)是上个月的兔子数量,是原来有的。
f(n-2)是可以生育的兔子数,即多出来的数量。第n-2个月开始后的第3个月是第n个月,此时第n-2个月时的兔子都可以生育了

阅读全文 »

垃圾回收机制的意义

Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。

ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。

阅读全文 »

官方说法

聚集索引

一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。

聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行 的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此 类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节 省成本。

当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束。

阅读全文 »

合并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序。合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行合并。

Definition of Merge Sort 

合并排序最大的优点是它的时间复杂度为O(nlgn),这个是我们之前的选择排序和插入排序所达不到的。他还是一种稳定性排序,也就是相等的元素在序列中的相对位置在排序前后不会发生变化。他的唯一缺点是,需要利用额外的N的空间来进行排序。

阅读全文 »

本篇开始学习排序算法。排序与我们日常生活中息息相关,比如,我们要从电话簿中找到某个联系人首先会按照姓氏排序、买火车票会按照出发时间或者时长排序、买东西会按照销量或者好评度排序、查找文件会按照修改时间排序等等。在计算机程序设计中,排序和查找也是最基本的算法,很多其他的算法都是以排序算法为基础,在一般的数据处理或分析中,通常第一步就是进行排序,比如说二分查找,首先要对数据进行排序。在Donald Knuth。 的计算机程序设计的艺术这四卷书中,有一卷是专门介绍排序和查找的。

阅读全文 »

前面讲解了平衡查找树中的2-3树以及其实现红黑树。2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key。

维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。普遍运用在数据库和文件系统。”

阅读全文 »