自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Venus专栏

将所学所想用自己的语言表述出来。

  • 博客(45)
  • 收藏
  • 关注

原创 【连载】大话系统架构决策 - 伸缩性

前言在单机应用时代,换句话说,如果你的应用就部署一个实例,并没有伸缩性的概念。伸缩性是针对分布式系统的场景下,在有意义。而且现在的大型分布式系统,对于伸缩性是非常重视的,因为现在的系统运维都希望机器或容器能够动态扩容。比如,淘宝的双11、京东的618等大型促销活动,其流量和压力都是平时的很多倍,但是总不能要求平时就用这么多的部署资源,这会很浪费,所以动态扩容就显得很有必要了。老规矩,先来定义一下伸缩

2016-06-10 14:53:50 761

原创 【连载】大话系统架构决策 - 易用性

前言为什么要谈易用性呢?其实是因为博主从事软件行业长久以来,另一最烦躁的,也是经常听到身边同事抱怨的一句话就是:我靠!天啦撸!这个API好难用啊!!!其实难用就是消费方对于提供方所提供资源(服务或能力)的最直观的不满用词。这个时候,你要真想让消费方说哪些地方难用?估计他只会告诉你:哇,你这个参数命名很让我费解啊,完全不知道什么意思,而且还为文档!老规矩,在详细阐述之前,我们尝试定义这个特性(关注点)

2016-06-09 07:13:37 1245

原创 【连载】大话系统架构决策 - 灵活性

前言为什么要首先谈灵活性呢?其实是因为博主从事软件行业长久以来,最烦躁的,也是经常听到身边同事抱怨的一句话就是:我靠!天啦撸!需求又变啦!!!其实需求变更就涉及到系统架构的特性(关注点)之灵活性。系统灵活性高,那么任你需求如何变更,我自岿然不动!就像九阳真经中所说的“他强由他强,清风拂山冈。他横任他横,明月照大江。”反之,微末变更也会让我哭爹喊娘,埋头做码畜!既然要谈灵活性,那么我首先来尝试定义下这

2016-06-06 21:05:14 1732

翻译 【连载】关系型数据库是如何工作的?(20) - 查询管理器之优化器

真正的优化器上边虽然说了那么多,但是都偏于理论,因为我是一个开发者不是一个研究员,所以我更喜欢说一些具体的例子。 让我们来看看SQLite优化器具体是怎么优化的。它非常简单,因此它也采用了最简单的优化方法:基于贪婪算法,并且应用一些额外的规则来尽可能减少执行计划的可能性:SQLite从来不会重新排序CROSS JOIN的表;join采用nested joins;outer joins通常是以

2016-06-05 14:09:42 445

翻译 【连载】关系型数据库是如何工作的?(19) - 查询管理器之贪婪算法

贪婪算法对于非常大的查询或者对速度要求很高的查询,还有一种贪婪算法可以应用。其思想就是应用一个规则(试探或者启发式)来一步步增量的构建执行计划。用这个规则贪婪算法会在有限时间内找到最好的算法(译者注:不是实际意义上最好的,只是说在要求的时间内最好的)。这个算法总是以一个join开始,然后在每一步总是应用相同的规则增加一个join。我们举一个简单的例子:5张表(A, B, C, D, E)的4次joi

2016-05-21 10:12:16 476

翻译 【连载】关系型数据库是如何工作的?(18) - 查询管理器之动态编程

一个关系数据库会尝试我之前介绍的多种方式,优化器的真正工作是在有限的时间内找到较优的方案。 大部分时候,优化器都找不到最优的方案,而只能找到较优的方案。 对于小查询做一个粗暴的计算是可行的,对于中等查询为了粗暴计算,也有一种方法避免不必要的计算,其称为:动态编程。动态编程其思想就是很多执行计划其实是很相似的,比如下图:它们都有相同的子树(A join B),因此我们可以不用每个执行计划都计算一次

2016-05-21 08:47:26 327

翻译 【连载】关系型数据库是如何工作的?(17) - 查询管理器之优化示例

我们已经介绍了3种类型的join。现在我们需要连接5张表获取一个人的完整信息,一个人信息包括:多个移动电话多个电子邮件多个地址多个银行账户那么我们需要下面的查询语句:SELECT * from PERSON, MOBILES, MAILS,ADRESSES, BANK_ACCOUNTSWHEREPERSON.PERSON_ID = MOBILES.PERSON_ID

2016-05-17 19:58:35 312

翻译 【连载】关系型数据库是如何工作的?(16) - 查询管理器之Merge Join

归并连接是唯一的生成排序结果的连接方式。其可以划分为两步:排序操作:对两个输入结果集按照连接字段排序;归并操作:归并经过排序的结果集到一起。排序之前我们已经介绍过归并排序,在这归并排序是一个好的算法但不是最好的,如果内存足够会有更好的算法。 有些场景下数据集已经经过了排序,例如:如果表示自然排序的,比如一张按照索引组织数据的表;如果连接条件中的关系是一个索引;如果连接一个查询过程中已经

2016-05-16 20:09:37 328

翻译 【连载】关系型数据库是如何工作的?(15) - 查询管理器之Hash Join

Hash连接在很多情况下都比嵌套循环连接有低的成本。其主要思路是:1) 拿到内关系中的所有元素;2) 利用一个Hash函数构建一个内存Hash表;3) 从外关系中一个一个的取出元素;4) 利用Hash函数计算每个元素的Hash值,找到Hash表中关联的桶;5) 如果桶中有元素和当前外层关系元素相等,则匹配成功。为了简化计算时间复杂度,需要做一些假定:内关系被划分为X个桶;利用Hash

2016-05-14 15:24:15 333

翻译 【连载】关系型数据库是如何工作的?(14) - 查询管理器之Nested Join

现在我们获取到了数据,让我们来关联它们吧。

2016-05-14 14:42:47 434

翻译 【连载】关系型数据库是如何工作的?(13) - 查询管理器之Access Path

所有现代数据库都是使用基于成本的优化策略来优化查询。其核心思想是评估每一个操作的成本,然后找到最便宜的一系列操作并得到结果,这样就找到了降低查询成本的最优方案。为了理解成本优化器是怎么工作的,我认为举一个例子来感受这个任务背后的复杂性是一种好的方式。在这一部分,先介绍两张表的3种常用方式,我们会看到即时是最简单的join查询,优化器也需要做很多工作。最后,我们会介绍真正的优化器是怎么工作的。对于上述

2016-05-12 21:13:11 622

翻译 【连载】关系型数据库是如何工作的?(12) - 查询管理器之Statistics

在学习数据库如何优化查询之前,我们必须先讲讲统计这件事,因为没有统计信息,数据库会变的很愚蠢导致没法优化或者优化效果很差。数据库究竟需要哪种统计信息呢?首先,我们必须简短的介绍下数据库和操作系统是如何存储数据的。它们的最小存储单位称为页或者块,每一页大小为4K或者8K。这就意味着,如果你存储1K大小的数据,同样会占用一页,如果一页是8K,那么就会浪费7K的存储空间。回到统计,当你要求数据库统计时,它

2016-05-11 19:05:18 497

翻译 【连载】关系型数据库是如何工作的?(11) - 查询管理器之rewriter

在重写这一步,我们拿到了查询SQL的内部表示,重写的目的是:预优化SQL避免不必要的操作帮助优化器找到尽可能好的解决方案重写器会在查询上匹配一系列规则,如果匹配一个规则就应用它重写查询,以下是部分可选的规则:视图合并:如果你在查询中用了视图,那么视图就会被转换为一段代码;优化子查询:由于一个子查询非常难以优化,因此重写器会修改子查询并删除子查询。 例如:SELECT PERSON.*

2016-05-09 21:13:06 2058

翻译 【连载】关系型数据库是如何工作的?(10) - 查询管理器之parser

解析器会检查每条语句都会的关键字语法正确性,如果一条语句语法有误,解析器会拒绝本次请求。例如:如果把”SELECT”写成”SLECT”,就会遭到拒绝。解析器还会进一步检查关键字出现的顺序,比如WHERE出现在SELECT之前就会被拒绝。另外,查询中的表明和字段名会被解析,解析器会使用数据库的运输局来进行对比检查:表是否存在。表中的字段是否存在。对于这种字段类型的操作是否合法,比如:不能将Str

2016-05-09 20:32:39 107

翻译 【连载】关系型数据库是如何工作的?(9) - 查询管理器

查询管理器查询管理是一个数据库强大与否的一个判断指标。通过查询管理,可以把一个糟糕的查询语句转换为一段快速执行的代码,代码执行后返回结果给客户端管理器。整个过程分为多步:查询首先被解析并检查其有效性;重写查询并删除不必要的操作,另外做一些预优化;为了提升性能进行必要的优化,最终转换为一个执行计划;编译执行计划;最后运行执行计划。在读了这一章节之后,如果对查询优化想更深入的理解,我推荐阅读

2016-05-09 13:10:29 1169

翻译 【连载】关系型数据库是如何工作的?(8) - 客户端管理器

客户端管理器就是处理和客户端之间的通信细节。

2016-05-09 12:40:12 449

翻译 【连载】关系型数据库是如何工作的?(7) - 数据库架构视图

现在我们可以看看数据库内部都有什么组件。一个数据库就是容易访问和修改的信息集合,实际上,一组简单的文件就可以做到。最简单的数据库SQLite就是由一组简单文件组成的,并且是一组精心设计的一组文件,它允许你:通过事务保证数据的安全性和一致性;即时海量数据也能保证快速处理数据。通常,一个数据的组件视图如下: 在写下这部分内容之前,我阅读了很多书籍和论文,每一个都有其特有的方式来描述

2016-05-09 09:37:30 1382 1

翻译 【连载】关系型数据库是如何工作的?(6) - Hash表

最后我们介绍的重要数据结构就是Hash表。

2016-05-07 15:58:21 2749

翻译 【连载】关系型数据库是如何工作的?(5) - B+Tree索引

虽然上一章节介绍的二叉搜索树在查询指定值时表现很好,但是当查询两个值之间的多个节点时,就会遇到很大的问题。因为需要遍历整个树的节点,并检查每个节点是否在指定的区间内。而且遍历整颗树是随机磁盘IO(译者注:随机IO会导致频繁的磁头换道,所以相比顺序IO来说非常耗时),所以我们需要找到一种更有效做范围查询的方法。为了解决这个难题,现代数据库修正了之前介绍的二叉搜索树,我们称修正后的数据结构为B+Tree

2016-05-07 09:47:00 3228

翻译 【连载】关系型数据库是如何工作的?(4) - 数组、二叉搜索树

在我们理解了隐藏在时间复杂度和排序后面的思想之后,我必须再谈谈3种数据结构了。它们极其重要,因为它们是现代数据库的基石。我也会顺便介绍下索引的概念。数组二维数组是最简单的数据结构,一张数据库表就可以看做一个二维数组,例如:二维数组就是一个既有行又有列的表:一行就表示一个主题(记录)一列就是描述主题(记录)的一个特性每一列存储同一个类型的数据(integer, string

2016-05-06 21:30:08 3338 1

翻译 【连载】关系型数据库是如何工作的?(3) - 归并排序

当你需要对一个集合排序时,你会怎么做?什么?你会调用排序函数…好吧,也算个好答案…但是对于数据库来说,你必须理解这个排序函数是如何工作的?有很多高效的排序算法,但让我们聚焦于最重要的一个:归并排序。你现在也许不太明白排序为什么很有用,但是到后续章节讲到查询排序你就会明白了。归并和很多有用的算法一样,归并排序其实是用于合并两个有序等长(N/2)数组,并且只需要N个操作。这个操作就被称为归并。让我们来看

2016-05-05 20:53:59 716

翻译 【连载】关系型数据库是如何工作的?(2) - 时间复杂度

基础知识很早之前,开发者必须准确的计算他们编写代码的操作指令数量,他们深刻理解使用的数据结构和算法,因为那个时候CPU计算能力和内存储存空间都很小,需要最大限度的利用起来,经不起浪费。在这一部分我会介绍一些这方面的内容,因为对于理解数据库它们确实很重要。另外,还会介绍数据库索引的概念。时间复杂度O(1) vs O(n2)时至今日,很多开发者都不关心时间复杂度,大部分时候也许他们是对的。但是当你需要处

2016-05-04 19:17:38 998

翻译 【连载】关系型数据库是如何工作的?(1) - 前言

译者说明这一系列博文翻译自一篇国外博主Christophe的博文《How does a relational database work》。该博文详细介绍了关系型数据库是如何工作的,其详实程度堪比专业数据库教材,但又更加精炼扼要,让读者能在短时间内理解数据库的底层原理。在此,对写出这篇长篇大作的原文作者Christophe表示由衷的敬意。由于该博文篇幅很长,因此会以连载的形式分为多篇来翻译。下面让我

2016-05-03 20:38:27 676

原创 Java程序通用场景性能分析

##问题场景 本地程序调用多个HTTP接口获取远端数据,然后拼装数据生成多个本地文件。##性能分析 > 实际上这个场景分为以下两步,我们实际需要分析影响每一步性能的因素,并进行优化。 1. 调用远程HTTP接口   本地和远端代码运行耗时占比不会很高,因为这都是CPU和内存操作,而真正耗时的应该是两者之间的网络交互; 2. 拼装数据并写本地文件   同理,对于CPU和内存操作的拼装数据来

2016-04-23 08:13:30 823

原创 消息中间件主备方案选型实践

背景介绍 该消息中间件由三个子系统组成:客户端SDK、Server和控制管理中心(Admin)。我们所说的主备主要是针对Server,而Server的节点是局部有状态的,具体而言就是发布无状态,但是拉取有状态。因此,对于发布而言,由于分布式部署所以本身具备高可用性;但是对于拉取,就存在单点的可用性问题。主备切换的关键问题 实现主备切换,需要解决两个核心问题: 1. 解决主备之间状态检

2016-04-20 21:00:44 1136

原创 基准测试工具sysbench安装和使用

sysbench介绍 SysBench是一个模块化的、跨平台、多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况。它主要包括以下几种方式的测试: 1. cpu性能 2. 磁盘io性能 3. 线程调度性能 4. 互斥锁性能 5. 数据库性能(OLTP基准测试) 6. 内存性能 目前sysbench主要支持 MySQL、pgsq、Or

2016-04-20 20:59:59 1284

原创 基于Netty的“请求-响应”同步通信机制实现

需求描述实现基于Netty的“请求-响应”同步通信机制。设计思路 Netty提供了异步IO和同步IO的统一实现,但是我们的需求其实和IO的同步异步并无关系。我们的关键是要实现请求-响应这种典型的一问一答交互方式。要实现这个需求,需要解决两个问题: 1. 请求和响应的正确匹配。 当服务端返回响应结果的时候,怎么和客户端的请求正确匹配起来呢?解决方式:通过客户端唯一的Req

2016-04-20 20:58:50 19470 5

原创 分析问题和学习知识的方法论区别

无论是分析问题还是学习知识,都是有规律可循的,遵循这个规律会事半功倍。这个规律,我们就可以称之为方法论。总结起来就是三个关键词:What、How、Why。但是二者不同之处在于三个关键点的组织顺序不一样。分析问题 方法论:Why -> What -> How 举例来说,现在我们要解决这样一个问题(需求):设计一个消息中间件的主备方案。 问题很明确,但是我们要怎么快速、清晰的分

2016-04-20 20:58:01 1197

原创 从无到有:软件项目过程敏捷实践

项目过程分解 通过本次消息中间件系统的全程参与,对于软件项目从无到有的生产过程有了较深入的了解,尤其对于架构设计的决策过程和依据,有了全面的认识。整个项目过程从无到有依次可以分解为九个过程,下面一一道来。(一)背景分析 主要是要分析清楚三个问题: 1. 这个项目的诉求是在什么业务现状下产生的? 2. 最终要解决什么问题? 3. 有什么价值? 为

2016-04-20 20:56:59 1850

原创 TCP协议Nagle算法和Delayed ACK相互影响实例分析

建议:阅读本文之前,最好对于TCP的发送、重发以及ACK机制有所了解。问题描述 最近在一个消息中间件系统(该消息中间件由客户端SDK和服务端Server组成)的性能测试时,发现每个请求的响应时间大概在40ms-50ms之间,这明显过大了。最终定位,是因为SDK没有禁用TCP的Nagle算法导致的。但其根本原理是因为TCP的Delayed Ack机制和Nagle Algorithm相互影响导致的

2016-04-20 20:56:25 1875

原创 Spymemcached操作队列分析

Spymemcached是一个Memcached(一个高性能内存对象缓存系统)的开源客户端程序。其他MC客户端还有xmemcached、Memcached Client for Java等。我们使用MC客户端程序与MC服务端通信,实现set、get缓存的操作,MC支持的协议类型包括:ASCII 文本协议和二进制协议。 Spymemcached使用Java NIO来实现,并且是单线程的,也就

2016-04-20 20:54:26 938

原创 Netty中ChannelHandler共享数据的方式

(一)成员变量public class DataServerHandler extends SimpleChannelHandler { // 成员变量 private boolean loggedIn; @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {

2016-04-20 20:52:51 12460 2

原创 MySQL应用并发优化实践

测试环境 应用结构: JWS(基于Play定制)+2次库表写入+分库分表 目标:TPS=5000 测试工具:Jmeter、Sysbench 并发线程:16性能目标 TPS>=5000现状 采用Jmeter在16并发场景下测试2分钟,最终并发在1200-1300之间,距离性能目标比较遥远。优化过程 首先考虑可能是代码某个地方有问题,暂时没有考虑数据库

2016-04-20 20:51:52 462

原创 JVM的Heap Memory和Native Memory

JVM管理的内存可以总体划分为两部分:Heap Memory和Native Memory。前者我们比较熟悉,是供Java应用程序使用的;后者也称为C-Heap,是供JVM自身进程使用的。Heap Memory及其内部各组成的大小可以通过JVM的一系列命令行参数来控制,在此不赘述。Native Memory没有相应的参数来控制大小,其大小依赖于操作系统进程的最大值(对于32位系统就是3~4G,各种系统

2016-04-20 20:49:52 16133 1

原创 C3P0连接超时分析

背景知识 c3p0是一个开源的、基于Java JDBC 规范的连接池管理框架。 官网地址:[http://www.mchange.com/projects/c3p0/]获取连接的过程 c3p0构造了一个Connection对象池。 在对象池中有空闲对象时或者没有达到对象池最大数量时,获取Connection都会成功返回。但是要注意,获取到的Connection不一定是可用的

2016-04-20 20:47:52 5424

原创 Java NIO写事件处理技巧

问题背景 OP_WRITE事件是在Socket发送缓冲区中的可用字节数大于或等于其低水位标记SO_SNDLOWAT时发生。正常情况下,都是可写的,因此一般不注册写事件。所以一般代码如下:while (bb.hasRemaining()) { int len = socketChannel.write(bb);取消 if (len < 0) { throw new E

2016-04-20 20:10:53 1918

原创 Linux学习系列-IO模型

IO模型是什么? 个人理解IO模型就是应用程序进行IO操作时和操作系统的通信和协作方式。为什么要学习IO模型? 我个人在学习Netty、Mina等网络编程框架时,搜索网上资料以及看书的过程中,经常会碰到一些名词:同步、异步、阻塞、非阻塞、事件驱动、轮询等等。这些名词乍一看,貌似我都懂,但是仔细分析时又发现似懂非懂,其实根本原因还是对于Unix的IO模型没有完全理解。Unix中有哪些IO模

2016-04-20 20:06:53 422

原创 Linux学习系列-轮询函数

理解这三个轮询函数差异的关键在于理解其轮询的文件描述符(socket也是文件)的数据结构。select轮询函数 函数定义:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exeptfds, struct timeval *timeout);// fd_set操作宏void FD_SET(int fd, fd_s

2016-04-20 20:03:51 2758

原创 Linux学习系列-信号

信号的定义和分类 信号是软件中断,提供了典型的异步机制。每个信号有一个编号,信号分为两类:非实时信号和实时信号。0-31编号属于非实时信号;31-63编号属于实时信号。为什么会分为这两类信号呢?这个主要是因为历史原因,首先实现的是非实时信号,非实时信号也成为不可靠信号,是因为其实现机制导致这类信号可能会丢失;而实时信号,由于存在排队机制,所以不会丢失。关于这点会在信号的处理过程图示中详细阐述。

2016-04-20 20:00:11 348

原创 Linux学习系列-浅析EXT2文件系统

注:EXT2文件系统是早期Unix系统采用的文件系统,目前比较新的EXT3也是继承了EXT2大部分特性拓展而来,因此学习Linux文件从EXT2开始会比较好入手。文件系统是什么? 标准定义参见维基百科【文件系统】。说说我自己作为程序员的理解,从我工作的角度看,狭义点说,文件系统就是专指信息在硬盘上的存储和组织方式。文件是文件系统中组织信息的最小逻辑单元,目录其实也是一种特殊的文件(其内容存储的

2016-04-20 19:58:54 346

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除