本文粗略说一下 MySQL 中常见的索引分类。

物理存储角度

  • 聚簇索引
  • 非聚簇索引

聚簇索引将数据存储与索引放到了一起,找到索引也就找到了数据。非聚簇索引将数据存储与索引分开,索引结构的叶子结点指向了数据对应的行。

InnoDB 中,在聚簇索引之上创建的索引,称之为辅助索引,辅助索引叶子结点存储的不是行的物理位置,而是主键值,因此辅助索引访问数据总是需要二次查找的。

一图顶千言,如下图所示:

由于聚簇索引是将数据跟索引结构放在一起的,因此一个表仅有一个聚簇索引。

聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一非空索引,如果没有这样的索引,InnoDB 会隐式定义一个主键来作为聚簇索引。


阅读全文 »

本文描述一个 Java 多线程死锁问题,并演示使用 jstackarthas 工具来发现应用程序中的线程死锁。

先编写一段死锁的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class App {

public static void main(String[] args) {
String x = "x";
String y = "y";
Thread a = new Thread(new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
synchronized (x) {
System.out.println(String.format("Thread %s Start %s", threadName, "------"));
System.out.println(String.format("Thread %s, x = %s", threadName, x));
synchronized (y) {
System.out.println(String.format("Thread %s, y = %s", threadName, y));
}
System.out.println(String.format("Thread %s End %s", threadName, "------"));
}
}
});

Thread b = new Thread(new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
synchronized (y) {
System.out.println(String.format("Thread %s Start %s", threadName, "------"));
System.out.println(String.format("Thread %s, y = %s", threadName, y));
synchronized (x) {
System.out.println(String.format("Thread %s, x = %s", threadName, x));
}
System.out.println(String.format("Thread %s End %s", threadName, "------"));
}
}
});

a.start();
b.start();
}
}

运行以上代码,发现如下输出:

1
2
3
4
Thread Thread-0 Start ------
Thread Thread-0, x = x
Thread Thread-1 Start ------
Thread Thread-1, y = y

由于 Thread-0 和 Thread-1 均没有输出 End 信息,可知线程陷入了死锁。


jstack 分析

jstack 是 jdk 自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。

Usage:

阅读全文 »

Dubbo 内置了 4 种负载均衡策略

  • RandomLoadBalance:随机负载均衡,随机选择一个服务结点,跟权重相关。该策略是 Dubbo默认负载均衡策略。
  • RoundRobinLoadBalance:轮询负载均衡,轮询选择一个服务结点,跟权重相关。
  • LeastActiveLoadBalance:最少活跃调用数,相同的活跃数随机选择一个结点,跟权重相关。实现方式是对活跃数值前后计数差。使得慢的结点收到更少的请求,因为越慢的结点前后计数差越大。
  • ConsistentHashLoadBalance:一致性哈希负载均衡,即相同的参数的请求总是落在同一个服务结点上。

通过观察类之间依赖图,可以快速帮我们梳理其之间的关系,如下图所示:

实践

纸上得来终觉浅,觉知此时要躬行。

Dubbo 中负载均衡的源码可自行通过源码来学习,为了加深印象,这里我以 Dubbo 源码中的思路来实现这四个负载均衡策略。

准备工作

定义结点接口

这里我们不实现 Dubbo 中的 Invoker,以一个结点类 Endpoint 代替。

阅读全文 »

死锁是指两个或多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象

示例

先用一个示例来演示一下数据库死锁的情况。本示例基于 MySQLInnoDB 存储引擎。

表结构

我们先建一个 wallet 表,表结构如下

1
2
3
4
5
6
7
8
mysql> DESC wallet;
+---------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| id | bigint(20) unsigned | NO | PRI | NULL | |
| user_id | bigint(20) unsigned | NO | UNI | 0 | |
| balance | bigint(20) | NO | | 0 | |
+---------+---------------------+------+-----+---------+-------+

开启事务 A,并修改 id 为 1 的记录

1
2
3
4
5
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE wallet SET balance = balance + 100 WHERE id = 1;
Query OK, 1 row affected (0.00 sec)

开启事务 B,并修改 id 为 2 的记录

1
2
3
4
5
6
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE wallet SET balance = balance + 100 WHERE id = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
阅读全文 »

镜像管理

查询所需的镜像

  • Usage:

    docker search [OPTIONS] TERM

  • Options:

    -f --filter :根据提供的条件过滤输出

    --format :使用 Go 模板进行漂亮的打印搜索

    --limit :最大搜索结果数(默认为 25)

    --no-trunc:不要截断输出

  • Example:

1
docker search mysql

安装镜像

  • Usage:

    docker pull [OPTIONS] NAME[:TAG|@DIGEST]

  • Options:

    -a --all-tags:下载存储库中的所有标记镜像

    --disable-content-trust:跳过图像验证(默认为 true)

  • Example:

    1
    2
    3
    4
    5
    6
    7
    8
    # 安装MySQL的5.7.24版本
    docker pull mysql:5.7.24
    # 缺省TAG时默认安装最新版本
    docker pull mysql
    # 安装所有版本
    docker pull -a mysql
    # 安装zookeeper
    docker pull zookeeper

查看镜像信息

Usage:

docker images [OPTIONS] [REPOSITORY[:TAG]]

Options:

阅读全文 »

参数配置

查看所有参数

1
mysql> SHOW VARIABLES;

慢查询、索引相关的参数

查看慢查询日志是否打开

Usage:

1
mysql> SHOW VARIABLES LIKE '%slow_query_log%';

Result:

Variable_name Value
slow_query_log OFF
slow_query_log_file /var/lib/mysql/17998065ff2d-slow.log

打开慢查询日志

阅读全文 »

本文简单介绍一下数据库的事务隔离级别,所用数据库采用 MySQLMySQL 提供了两种事务性的存储引擎 InnoDBNDB Cluster,本文示例采用 InnoDB 存储引擎。

查看当前数据的事务隔离级别

1
2
3
4
5
6
7
8
-- 查看当前数据库事务隔离级别
mysql> SHOW VARIABLES LIKE '%transaction_isolation%';
-- 或者
mysql> SELECT @@transaction_isolation;
-- 低版本的 MySQL 查看事务隔离级别的属性是不一样的
mysql> SHOW VARIABLES LIKE '%tx_isolation%';
-- 或者
mysql> SELECT @@tx_isolation;

不同的事务隔离级别所面对的问题

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)
  • 脏读:事务 A 读取了事务 B 更新的数据,然后 B 回滚操作,那么 A 读取到的数据是脏数据。

  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中,对数据作了更新并提交,导致事务 A 多次读取同一数据时,结果不一致。

  • 幻读:系统管理员 A 将数据库中所有学生的成绩从具体分数改为 ABCDE 等级,但是系统管理员 B 就在这个时候插入了一条具体分数的记录,当系统管理员 A 改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

小结:不可重复读和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要使用间隙锁或临键锁来锁定范围。


脏读的场景

阅读全文 »

记录常用的 JVM 参数,持续更新 …

堆内存设置

-Xms128M : 设置 java 程序启动时堆内存 128M(默认为物理内存 1/64,且小于 1G),阿里 p3c 文档中推荐 Xmx 与 Xms 配置同样的大小,避免 GC 后调整堆大小带来的压力

-Xmx256M : 设置最大堆内存 256M,超出后会出现 OutOfMemoryError(默认为物理内存 1/64,且小于 1G)

-Xmn10M : 设置新生代区域大小为 10M

-XX:NewSize=2M : 设置新生代初始大小为 2M

-XX:MaxNewSize=2M : 设置新生代最大值为 2M

-Xss1M : 设置线程栈的大小 1M(默认 1M)

-XX:MinHeapFreeRatio=40 : 设置堆空间最小空闲比例(默认 40)(当 Xmx 与 Xms 相等时,该配置无效)

-XX:MaxHeapFreeRatio=70 : 设置堆空间最大空闲比例(默认 70)(当 Xmx 与 Xms 相等时,该配置无效)

阅读全文 »

curl 是十分常用的命令,通常我们用这个命令来请求 Web 服务器。一些常见的构造 HTTP 请求的客户端(如 Postman)关于项目协作的功能都是商业化版本才有的,团队开发过程中通过维护接口的 curl 命令脚本可以低成本的代替一些商业化软件的功能。

下面介绍一下 curl 命令的常见用法。

基础用法

请求一个 URL

1
curl http://www.baidu.com/

-X

使用 -X 参数可以指定 HTTP Method

1
curl -X POST http://www.baidu.com/

-H, –header

使用 -H 或者 –header 参数可以添加 HTTP 的请求头

阅读全文 »

介绍

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件(涵盖了服务治理、配置管理、限流降级以及阿里开源生态和商业生态的诸多组件),方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。

Spring Cloud 是什么

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems .

Spring Cloud 为开发者提供了快速构建分布式系统的模型。Spring Cloud 除了抽象了分布式系统里的一些接口,并且提供了一系列开箱即用的组件。

Spring Cloud 更详细的介绍以及相关的组件,可以参考官网

Spring Cloud Alibaba 对 Spring Cloud 的意义

  • Spring Cloud AlibabaSpring Cloud 体系中是一个套件,类似于 Netflix OSS,为开发者提供了更多的选择。
  • Netflix OSS 诸多重要组件先后宣布停止新功能开发的大背景下 Spring Cloud Alibaba 作为一个高速迭代中的新生项目无疑是更合适的选择。
  • 将国内非常流行的 DubboRocketMQ 等融入 Spring Cloud 体系,使得应用的接入和改造的成本更低。
  • Spring Cloud Alibaba 是中文文档最全的 Spring Cloud 组件。

组件

阅读全文 »