diff --git a/docs/high-performance/images/read-and-write-separation-and-library-subtable/horizontal-slicing-database.png b/docs/high-performance/images/read-and-write-separation-and-library-subtable/horizontal-slicing-database.png new file mode 100644 index 00000000..77f43e68 Binary files /dev/null and b/docs/high-performance/images/read-and-write-separation-and-library-subtable/horizontal-slicing-database.png differ diff --git a/docs/high-performance/images/read-and-write-separation-and-library-subtable/two-forms-of-sub-table.png b/docs/high-performance/images/read-and-write-separation-and-library-subtable/two-forms-of-sub-table.png new file mode 100644 index 00000000..8680ee4d Binary files /dev/null and b/docs/high-performance/images/read-and-write-separation-and-library-subtable/two-forms-of-sub-table.png differ diff --git a/docs/high-performance/images/read-and-write-separation-and-library-subtable/vertical-slicing-database.png b/docs/high-performance/images/read-and-write-separation-and-library-subtable/vertical-slicing-database.png new file mode 100644 index 00000000..67c857a7 Binary files /dev/null and b/docs/high-performance/images/read-and-write-separation-and-library-subtable/vertical-slicing-database.png differ diff --git a/docs/high-performance/read-and-write-separation-and-library-subtable.md b/docs/high-performance/read-and-write-separation-and-library-subtable.md index 274434ae..0f04e0bd 100644 --- a/docs/high-performance/read-and-write-separation-and-library-subtable.md +++ b/docs/high-performance/read-and-write-separation-and-library-subtable.md @@ -109,8 +109,6 @@ MySQL binlog(binary log 即二进制日志文件) 主要记录了 MySQL 数据 **MySQL 主从复制是依赖于 binlog 。另外,常见的一些同步 MySQL 数据到其他数据源的工具(比如 canal)的底层一般也是依赖 binlog 。** - - ## 分库分表 读写分离主要应对的是数据库读并发,没有解决数据库存储问题。试想一下:**如果 MySQL 一张表的数据量过大怎么办?** @@ -121,40 +119,53 @@ MySQL binlog(binary log 即二进制日志文件) 主要记录了 MySQL 数据 ### 什么是分库? -**分库** 就是将数据库中的数据分散到不同的数据库上。 +**分库** 就是将数据库中的数据分散到不同的数据库上,可以垂直分库,也可以水平分库。 -下面这些操作都涉及到了分库: +**垂直分库** 就是把单一数据库按照业务进行划分,不同的业务使用不同的数据库,进而将一个数据库的压力分担到多个数据库。 -- 你将数据库中的用户表和用户订单表分别放在两个不同的数据库。 -- 由于用户表数据量太大,你对用户表进行了水平切分,然后将切分后的 2 张用户表分别放在两个不同的数据库。 +举个例子:说你将数据库中的用户表、订单表和商品表分别单独拆分为用户数据库、订单数据库和商品数据库。 + +![垂直分库](./images/read-and-write-separation-and-library-subtable/vertical-slicing-database.png) + +**水平分库** 是把同一个表按一定规则拆分到不同的数据库中,每个库可以位于不同的服务器上,这样就实现了水平扩展,解决了单表的存储和性能瓶颈的问题。 + +举个例子:订单表数据量太大,你对订单表进行了水平切分(水平分表),然后将切分后的 2 张订单表分别放在两个不同的数据库。 + +![水平分库](./images/read-and-write-separation-and-library-subtable/horizontal-slicing-database.png) ### 什么是分表? **分表** 就是对单表的数据进行拆分,可以是垂直拆分,也可以是水平拆分。 -**何为垂直拆分?** - -简单来说,垂直拆分是对数据表列的拆分,把一张列比较多的表拆分为多张表。 +**垂直分表** 是对数据表列的拆分,把一张列比较多的表拆分为多张表。 举个例子:我们可以将用户信息表中的一些列单独抽出来作为一个表。 -**何为水平拆分?** - -简单来说,水平拆分是对数据表行的拆分,把一张行比较多的表拆分为多张表。 +**水平分表** 是对数据表行的拆分,把一张行比较多的表拆分为多张表,可以解决单一表数据量过大的问题。 举个例子:我们可以将用户信息表拆分成多个用户信息表,这样就可以避免单一表数据量过大对性能造成影响。 -[《从零开始学架构》](https://time.geekbang.org/column/intro/100006601?code=i00Nq3pHUcUj04ZWy70NCRl%2FD2Lfj8GVzcGzZ3Wf5Ug%3D) 中的有一张图片对于垂直拆分和水平拆分的描述还挺直观的。 +水平拆分只能解决单表数据量大的问题,为了提升性能,我们通常会选择将拆分后的多张表放在不同的数据库中。也就是说,水平分表通常和水平分库同时出现。 -![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/662ea3bda90061d0b40177e3a46fefc3.jpg) +![分表](./images/read-and-write-separation-and-library-subtable/two-forms-of-sub-table.png) ### 什么情况下需要分库分表? 遇到下面几种场景可以考虑分库分表: -- 单表的数据达到千万级别以上,数据库读写速度比较缓慢(分表)。 -- 数据库中的数据占用的空间越来越大,备份时间越来越长(分库)。 -- 应用的并发量太大(分库)。 +- 单表的数据达到千万级别以上,数据库读写速度比较缓慢。 +- 数据库中的数据占用的空间越来越大,备份时间越来越长。 +- 应用的并发量太大。 + +### 常见的分片算法有哪些? + +分片算法主要解决了数据被水平分片之后,数据究竟该存放在哪个表的问题。 + +- **哈希分片** :求指定 key(比如 id) 的哈希,然后根据哈希值确定数据应被放置在哪个表中。哈希分片比较适合随机读写的场景,不太适合经常需要范围查询的场景。 +- **范围分片** :按照特性的范围区间(比如时间区间、ID区间)来分配数据,比如 将 `id` 为 `1~299999` 的记录分到第一个库, `300000~599999` 的分到第二个库。范围分片适合需要经常进行范围查找的场景,不太适合随机读写的场景(数据未被分散,容易出现热点数据的问题)。 +- **地理位置分片** :很多 NewSQL 数据库都支持地理位置分片算法,也就是根据地理位置(如城市、地域)来分配数据。 +- **融合算法** :灵活组合多种分片算法,比如将哈希分片和范围分片组合。 +- ...... ### 分库分表会带来什么问题呢? diff --git a/docs/java/jvm/jvm-parameters-intro.md b/docs/java/jvm/jvm-parameters-intro.md index 4b9bf196..54f7ae9b 100644 --- a/docs/java/jvm/jvm-parameters-intro.md +++ b/docs/java/jvm/jvm-parameters-intro.md @@ -67,9 +67,9 @@ GC 调优策略中很重要的一条经验总结是这样说的: > 将新对象预留在新生代,由于 Full GC 的成本远高于 Minor GC,因此尽可能将对象分配在新生代是明智的做法,实际项目中根据 GC 日志分析新生代空间大小分配是否合理,适当通过“-Xmn”命令调节新生代大小,最大限度降低新对象直接进入老年代的情况。 -另外,你还可以通过**`-XX:NewRatio=`**来设置新生代和老年代内存的比值。 +另外,你还可以通过 **`-XX:NewRatio=`** 来设置老年代与新生代内存的比值。 -比如下面的参数就是设置新生代(包括Eden和两个Survivor区)与老年代的比值为1。也就是说:新生代与老年代所占比值为1:1,新生代占整个堆栈的 1/2。 +比如下面的参数就是设置老年代与新生代内存的比值为1。也就是说老年代和新生代所占比值为1:1,新生代占整个堆栈的 1/2。 ``` -XX:NewRatio=1 @@ -141,3 +141,4 @@ JVM具有四种类型的*GC*实现: - [从实际案例聊聊Java应用的GC优化-美团技术团队](https://tech.meituan.com/2017/12/29/jvm-optimize.html) - [JVM性能调优详解](https://www.choupangxia.com/2019/11/11/interview-jvm-gc-08/) (2019-11-11) - [JVM参数使用手册](https://segmentfault.com/a/1190000010603813) +- diff --git a/docs/open-source-project/tutorial.md b/docs/open-source-project/tutorial.md index f30d834c..d2041356 100644 --- a/docs/open-source-project/tutorial.md +++ b/docs/open-source-project/tutorial.md @@ -7,8 +7,8 @@ icon: "book" ## Java - **[JavaGuide](https://github.com/Snailclimb/JavaGuide "JavaGuide")** :【Java 学习+面试指南】 一份涵盖大部分 Java 程序员所需要掌握的核心知识。 -- **[interview-guide](https://github.com/csguide-dabai/interview-guide)** :总结了后端面试八股文中的重点,希望能帮助各位准备互联网开发岗校招面试的同学。 - **[toBeBetterJavaer](https://github.com/itwanger/toBeBetterJavaer)** :一份通俗易懂、风趣幽默的 Java 学习指南,内容涵盖 Java 基础、Java 集合框架、Java 并发编程、JVM、Java 企业级开发(Git、SSM、Spring Boot)等知识点。 +- **[interview-guide](https://github.com/csguide-dabai/interview-guide)** :总结了后端面试八股文中的重点,希望能帮助各位准备互联网开发岗校招面试的同学。 - **[advanced-java](https://github.com/doocs/advanced-java "advanced-java")** :互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识。 - **[toBeTopJavaer](https://github.com/hollischuang/toBeTopJavaer "toBeTopJavaer")** :Java 工程师成神之路 。 - **[technology-talk](https://github.com/aalansehaiyang/technology-talk)** : 汇总 java 生态圈常用技术框架、开源中间件,系统架构、数据库、大公司架构案例、常用三方类库、项目管理、线上问题排查、个人成长、思考等知识