expand-and-contract-pattern-cover.png

引言

数据库表结构的设计会随着与之交互的软件变化而不可避免地演进。能够安全、可靠地将表结构过渡到新需求至关重要。

虽然数据库迁移工具通常可以更新实际的数据结构,但数据本身也必须转换到新格式、迁移到不同的表或列,并更新以符合新的预期。这些过程虽然不一定复杂,但在客户端仍在使用的线上系统中执行时尤为敏感。

幸运的是,有一种称为扩展与收缩模式的多步骤流程,可在不中断系统服务的情况下,安全地逐步将客户端迁移到使用新的数据结构。本指南将探讨扩展与收缩模式是什么,它如何实现新旧结构之间的无缝过渡,以及如何将其应用于各种数据库转换。

什么是扩展与收缩模式?

扩展与收缩模式是一种数据库管理员和软件开发人员可用来将数据从旧数据结构迁移到新数据结构而不影响系统正常运行时间的流程。它通过一系列独立的步骤来应用变更,旨在后台引入新结构、为线上使用准备数据,然后无缝切换到新结构。

该流程可用于修改许多正在使用的接口,但对数据库表结构变更尤其有用。除了将数据和客户端迁移到新数据结构之外,扩展与收缩模式还有一个优势:如果在过程中的任何阶段出现问题,或者需求发生变化,你都可以轻松地回滚变更。

阅读全文 »

引言

修改数据库结构通常被称为“迁移”到新schema。虽然用于修改结构本身的操作通常相对简单,但确保所管理的数据保持可访问、一致且语义正确,需要谨慎和规划。

在本文,我们将介绍团队可用于更新数据库schema及相关代码库的一些策略,并讨论每种方案在解决潜在问题方面的效果。我们将探讨一些通用的应用程序部署模式,以及几种专门针对数据库场景设计的选项。

数据库相关部署策略面临的挑战

在包含数据库的环境中部署变更时,可能会出现一系列潜在问题。其中一些问题源于客户端代码库与数据库结构之间的不一致,另一些则源于对现有数据进行更新所带来的影响。

阅读全文 »

引言

数据库模式(Database schemas)定义了关系型数据库所管理数据的结构与相互关系。尽管在项目初期制定一个经过深思熟虑的schema至关重要,但随着需求的不断演进,对初始schema进行更改往往难以甚至无法避免。由于schema决定了数据的形态与边界,任何变更都必须谨慎实施,以符合使用该schema的应用程序的预期,并避免丢失数据库系统当前已存储的数据。

在本文中,我们将介绍什么是数据库模式迁移、它们解决了哪些问题以及不同的实现策略。我们还将探讨它们所解决的各种痛点以及可能带来的一些潜在陷阱。

什么是数据库迁移(Database Migrations)

数据库迁移(Database migrations),又称 schema 迁移、数据库 schema 迁移,或简称迁移,是一组受控的变更,用于修改关系型数据库中对象的结构。迁移帮助将数据库 schema 从当前状态过渡到新的期望状态,无论是添加表和列、删除元素、拆分字段,还是更改类型和约束。

迁移以编程管理的方式对数据结构做增量的、通常是可逆的变更。数据库迁移工具的目标是使数据库变更可重复、可共享且可测试,同时避免数据丢失。通常,迁移工具会生成描述将数据库从已知状态转换到新状态所需的确切操作集的产物。这些产物可以被纳入常规的版本控制系统中,以便跟踪变更并在团队成员之间共享。

尽管防止数据丢失通常是迁移工具的目标之一,但删除或破坏性修改当前包含数据的结构可能会导致数据被删除。为应对这种情况,迁移通常是一个受监督的过程,涉及检查生成的变更脚本,并进行必要的修改以保留重要信息。

阅读全文 »

理想情况下,Kubernetes 节点的存储资源是无限的,Pod 和容器也不会因为磁盘空间不足而运行失败。但是在现实世界中,节点的资源是有限的。节点无法凭空生成更多的磁盘空间,当节点的可用存储容量不足时,就会出现磁盘压力问题。不过我们可以通过正确的监控和管理,可以防止磁盘压力问题影响workload的性能。

什么是磁盘压力问题

在 Kubernetes 中,节点磁盘压力是指节点的可用磁盘空间不足,导致节点无法运行新的 Pod。当该问题发生时,Kubernetes 会触发节点压力驱逐(node-pressure eviction),将一些 Pod 从节点中驱逐出去,以释放磁盘空间。

重要的是,kubernetes 节点磁盘压力问题通常是逐个节点发生的。换句话说,一个节点的磁盘空间不足,不会影响其他节点的运行。这是因为 workload 只能使用所在节点的磁盘空间。因此,如果某个Pod开始占用过多的磁盘空间,它也只会使用所在节点的磁盘空间,而不会影响其他节点的运行。

也就是说,如果你部署了很多存储密集型的 Pod,那么大多数的节点甚至所有节点都可能面临磁盘压力问题。

我们还应明确知晓,节点磁盘压力发生在节点持久化存储空间不足时,而不是指由 RAM 提供的临时或短暂存储空间。

阅读全文 »

什么是B树

B树在许多软件中都扮演着基础角色,尤其是数据库管理系统(DBMS)。MySQL、PostgreSQL、MongoDB、Dynamo 等众多系统都依赖 B 树通过索引来高效地查找数据。当你读完这篇文章时,你将了解 B 树和 B+ 树的工作原理,数据库为何使用它们来构建索引,以及为什么将 UUID 作为主键可能不是一个好主意。你还将有机会体验我们讨论的数据结构的交互式动画。准备好点击按钮吧。

计算机科学领域有大量的数据结构可供选择,用于在计算机上存储、搜索和管理数据。B树就是这样一种数据结构,它在数据库应用中被广泛使用。B树以计算机程序员所说的树状结构存储被称为键值对的数据。对于不熟悉计算机科学家如何使用“树”这个术语的人来说,它实际上看起来更像一个根系。

下面是本博客的第一个交互式组件。借助它,你可以直观地看到B树的结构,还能了解在添加键值对以及更改每个节点的键值对数量时会发生什么。点击“添加”或“Add random”按钮几次来试试看,在我们深入细节之前,先直观感受一下它的工作原理。

阅读全文 »

通用唯一识别码(Universally Unique Identifiers,也称为 UUID)旨在让开发人员能够在不了解其他系统的情况下生成唯一的 ID,从而保证 ID 的唯一性。在分布式架构中,当有多个系统和数据库负责创建记录时,UUID 特别有用。你可能认为在数据库中使用 UUID 作为主键是个不错的主意,但如果使用不当,它们可能会严重影响数据库性能。

在本文中,你将了解在 MySQL 数据库中使用 UUID 作为主键的缺点。

阅读全文 »

头图

RESTful接口现在很普遍,但是如果你作为一名web开发者,你应该知道对于不同的情况如何去选择一个最合适的HTTP方法有点困难。

对于开发REST接口来说,更新一个资源是常见的事,这里有两个开发者经常使用的HTTP方法:PUTPATCH,一般你会选择哪一个?

这两个方法看起来作用相同,都是更新一个服务的资源,但它们底层确是完成不同的事情。本篇文章将帮助你理解PUT和PATCH请求之间的区别,以便你可以设计一个专业的生产级别的API。

阅读全文 »

问题描述

当一个Pod被执行删除操作后,却长时间的处于Terminating状态,发生这样的情况可能是因为:

  • Pod有一个与其关联的finalizer,这个finalizer的任务没有完成。
  • Pod对中断信号没有响应

当我们执行kubectl get pods命令时,你将会看到这样的信息:

NAME                     READY     STATUS             RESTARTS   AGE
nginx-7ef9efa7cd-qasd2   1/1       Terminating        0          1h
阅读全文 »

JDK(Java Deveplopment Kit)是一个用于开发java应用程序的软件开发环境。它包含了JRE(Java Runtime Environment)、解释器/加载器(Java)、编译器(javac)、打包模块(jar)、文档生成器(Javadoc)和其他java开发中所需要的工具。

JRE全称为Java Runtime Environment,并且也可以被写为Jave RTE。JRE为执行java程序提供了最小化的前提要求,它由Jave虚拟机(JVM)、核心类等组成。

下面来看一下JVM

  • Java虚拟机有一个运行规范,该规范的实现由Sun公司和其他公司来完成,并且各公司可以各自选择实现算法。

  • JVM是一个满足了JVM规范要求的计算机程序。

  • 每当在命令行中运行java程序时,一个JVM实例将会被创建。

pic

阅读全文 »

编译器(Compiler)和解释器(Interpreter)是两种不同的工具,都可以将编程语言脚本语言转换为机器语言

编译器可以将整个程序转换为目标代码(object code),这些目标代码通常存储在文件中。目标代码也被称为二进制代码,在进行链接(link)后可以被机器直接执行。典型的编译型程序语言有CC++

解释器(Interpreter)能够直接执行程序或脚本语言中编写的指令,而不需要预先将这些程序或脚本语言转换成目标代码或者机器码。典型的解释型语言有PerlPythonPHPMatlab

以下是关于编译器解释器有趣的方面:

  1. 编译器解释器都能将源代码(文本文件)转换为其他符号;都能生成语法树(parse tree);都能生成立即指令(immediate instructions,即该指令中要操作的数据已经包含在了指令中,而不是在指令中操作数据所在的地址)。它们的不同之处是,编译器包含了链接器(linker),生成独立的机器代码程序,而解释器是直接执行高级语言所描述的操作。

  2. 一旦程序被编译了,则它的源代码对于运行程序来说没用处了。而解释型程序的源代码在运行程序的时候是始终都需要被用到。

  3. 解释型程序一般会比编译型程序运行效率低。

  4. Java程序首先会被编译器编译成中间状态(即字节码),然后再被解释器执行。

0%