03 2024 档案
摘要:楔子 下面来说一下 ClickHouse 管理和运维相关的知识,该部分可以让 ClickHouse 变得更加安全与健壮。在前面演示的案例中,为了方便,我们一直使用默认的 default 用户,并且没有配置密码,这显然不符合生产环境的要求。所以接下来,我们就来介绍 ClickHouse 的权限、熔断机
阅读全文
摘要:楔子 我们知道 ClickHouse 自带两个库,分别是 default 和 system,default 是默认的数据库,我们创建表的时候如果不指定库名,那么默认会在 default 下创建。而 system 则是系统库,里面存放了大量与系统相关的表,通过这些系统表我们可以查看服务器的所有状态信息
阅读全文
摘要:楔子 纵使单节点性能再强,也会有遇到瓶颈的那一天,业务量的持续增长、服务器的意外故障,都是 ClickHouse 需要面对的洪水猛兽。但常言道:一个好汉三个帮,一个篱笆三个桩,放在计算机领域就是,一个节点不够,就多来几个节点,下面就来介绍一下 ClickHouse 的集群、副本与分片。 概述 集群是
阅读全文
摘要:执行计划 如果要在 ClickHouse 20.6 版本之前查看 SQL 语句的执行计划,需要在 config.xml 里面将日志级别设置为 trace。 <!-- 新版本默认是 trace --> <logger> <level>trace</level> </logger> 然后还要真正执行相应
阅读全文
摘要:楔子 在 ClickHouse 中还存在一些其它比较有意思的函数,我们来看一下。 and:计算多个值逻辑与连接的结果 该函数只能接收 整型、浮点型和 Null,其逻辑和 Python 中的 and 类似 SELECT and(1, 2, 0, Null, 3, 5); /* ┌─and(1, 2,
阅读全文
摘要:楔子 之前在介绍数据类型的时候,有一种没有说,就是 Map。Map 是什么想必无需多言,简单来说的话就是维护键值对之间的映射关系,可以通过键迅速定位到值。 下面先来创建一张表: -- 在定义 Map 的时候,必须要指定键值对的类型 CREATE TABLE table_map(a Map(Strin
阅读全文
摘要:下面来说一说日期和时间的相关操作。 toDate、toDateTime:将字符串转成 Date、DateTime SELECT toDate('2020-11-11 12:12:12') v1, toDateTime('2020-11-11 12:12:12') v2; /* ┌─────────v
阅读全文
摘要:下面来说一说字符串的相关操作。 empty:检测一个字符串是否为空,为空返回 1,不为空返回 0 notEmpty:检测一个字符串是否不为空,不为空返回 1,为空返回 0 SELECT empty(''), empty('satori'); /* ┌─empty('')─┬─empty('sator
阅读全文
摘要:楔子 这次来说一下 ClickHouse 中的聚合函数,因为和关系型数据库的相似性,本来聚合函数不打算说的,但是 ClickHouse 提供了很多关系型数据库中没有的函数,所以我们还是从头了解一下。 count:计算数据的行数,有以下几种方式: count(字段):计算该字段中不为 Null 的元素
阅读全文
摘要:楔子 在一般的关系型数据库中,相信很多人都不怎么使用数组这个结构,如果真的需要数组,那么会选择将其变成数组格式的字符串进行存储。但在 ClickHouse 中,数组的使用频率是非常高的,因为它内置了大量和数组有关的函数。 SELECT version(); /* ┌─version()─┐ │ 21
阅读全文
摘要:楔子 作为一款 OLAP 型的数据库,它的查询功能可谓是重中之重,而且我相信大家在绝大部分时间都在使用它的查询功能,事实上在日常运转的过程中,数据查询也是 ClickHouse 的主要工作之一。ClickHouse 完全使用 SQL 作为查询语言,能够以 SELECT 查询语句的形式从数据库中选取数
阅读全文
摘要:楔子 Everything is table(万物皆为表)是 ClickHouse 的一个非常有意思的设计思路,正因为 ClickHouse 是一款数据库,所以自然而然数据表就是它的武器,是它与外部进行交互的接口层。在数据表背后无论连接的是本地文件、HDFS、Zookeeper,还是其它服务,终端用
阅读全文
摘要:楔子 目前在 ClickHouse 中,按照特点可以将表引擎分为 6 个系列,分别是合并树、外部存储、内存、文件、接口和其它,每一个系列的表引擎都有独自的特点和使用场景。而其中最核心的当属 MergeTree 系列,因为它们拥有最为强大的性能和最为广泛的使用场景。 经过之前的介绍,我们知道 Merg
阅读全文
摘要:楔子 表引擎是 ClickHouse 中的一大特色,可以说表引擎决定了一张表最终的性格,比如数据表拥有何种特性、数据以何种形式被存储以及如何被加载。ClickHouse 拥有非常庞大的表引擎体系,总共有合并树、外部存储、内存、文件、接口和其它 6 大类 20 多种表引擎,而在这众多的表引擎中,又属合
阅读全文
摘要:楔子 日常工作中,我们更多地还是对数据表中的数据进行操作,而对于 OLAP 类型的数据库而言,这些操作还基本都是查询操作。不过查询涉及到的内容非常多,我们会单独展开,这里先看看如何进行增删改。 增 跟绝大部分关系型数据库一样,ClickHouse 使用 INSERT 语句进行数据的插入。并且 INS
阅读全文
摘要:楔子 在了解了 ClickHouse 的主要数据类型之后,接下来我们开始介绍 DDL 操作,DDL 操作提供了数据库和数据表的创建、修改以及删除操作,是最常用的功能之一。 数据库 数据库起到了命名空间的作用,可以有效规避命名冲突的问题,也为后续的数据隔离提供了支撑。任何一张数据表,都必须归属在某个数
阅读全文
摘要:楔子 作为一款分析型数据库,ClickHouse 提供了许多数据类型,它们可以划分为基础类型、复合类型和特殊类型。其中基础类型使 ClickHouse 具备了描述数据的基本能力,而另外两种类型则使 ClickHouse 的数据表达能力更加丰富和立体。 下面就来分门别类的介绍一下。 基础类型 基础类型
阅读全文
摘要:楔子 相较于 Hadoop 生态圈中的一些系统,ClickHouse 的安装显得尤为简单,因为它自成一体,在单节点的情况下不需要额外的依赖,集群的话后面会说。 ClickHouse 支持运行在主流 64 位 CPU 架构的 Linux 操作系统上,可以通过源码编译、预编译压缩包、Docker 镜像和
阅读全文
摘要:楔子 本系列的很多内容均来自于朱凯老师的《ClickHouse 原理解析与应用实践》。 Google 于 2003~2006 年相继发表了三篇论文:Google File System、Google MapReduce、Google Bigtable,将大数据的处理技术带进了大众视野,而 2006
阅读全文
摘要:楔子 这里我们需要先解释一下,为什么要阅读 Redis 源码。平常我们在基于 Redis 做应用开发时,可能只是将 Redis 作为一个缓存系统或是数据库来存取数据,并不会接触到源码层面的东西。比如,我们在做社交应用开发时,会将用户数据、关注信息等缓存在 Redis 中;在开发存储系统软件时,也会用
阅读全文
摘要:楔子 本次我想和你聊一聊在使用 Redis 时,可能会踩到的「坑」,如果你在使用 Redis 时,也遇到过以下这些「诡异」的场景,那很大概率是踩到「坑」了: 明明一个 key 设置了过期时间,怎么变成不过期了? 使用 O(1) 复杂度的 SETBIT 命令,Redis 竟然被 OOM 了? 执行 R
阅读全文
摘要:楔子 Redis 作为优秀的内存数据库,其拥有非常高的性能,单个实例的 QPS 能够达到 10W 左右。但也正因此如此,当我们在使用 Redis 时,如果发现操作延迟变大的情况,就会与我们的预期不符。可能你或多或少地遇到过以下这些场景: 在 Redis 上执行同样的命令,为什么有时响应很快,有时却很
阅读全文
摘要:楔子 之前我们了解了 Redis 主从节点集群模式,在这个模式下,如果从节点发生故障了,客户端可以继续向主节点或其它从节点发送请求,执行相关的操作。但如果是主节点发生故障了,那么显然会直接影响到从节点的同步,因为从节点没有相应的主节点可以进行数据复制操作了。 而且,如果客户端发送的都是读操作请求,那
阅读全文
摘要:楔子 主从同步(主从复制)是 Redis 高可用服务的基石,也是多机运行中最基础的一个。我们把主要存储数据的节点叫做主节点(master),把其它通过复制主节点数据的副本节点叫做从节点(slave),如下图所示: 在 Redis 中一个主节点可以拥有多个从节点,一个从节点也可以是其它从节点的主节点,
阅读全文
摘要:楔子 "限流"这种事情即使在生活中也很常见,比如我们银行办理业务,银行不可能给去的所有人同时服务,因为柜台就那么几个。所以可能一次只给 5 个人办理业务,其他的人只能在后面排队;再比如打饭等等,也是一样的道理。因为能提供服务的数量有限,所以必须要通过限流的方式。 在程序的层面上也是一样的,如果我们的
阅读全文
摘要:楔子 锁是多线程编程中的一个重要概念,它是保证多线程并发时顺利执行的关键。我们通常所说的锁是指程序中的锁,也就是单机锁,比如 Python threading 模块里面的 Lock 等等。因此锁主要用于并发控制,保证一项资源在任何时候只能被一个线程使用,如果其它线程也要使用同样的资源,必须排队等待上
阅读全文
摘要:楔子 前面我们介绍了如何通过 List 和 Pub/Sub 来实现一个消息队列,但很明显它们都有很严重的缺陷,作为消息队列是不合格的。而 Redis 作者也注意到了这一点,于是开发了 disque,目的是成为一个基于内存的分布式消息中间件。但该项目没什么人关注,于是在 5.0 的时候将 disque
阅读全文
摘要:楔子 Redis 虽然是一个缓存,但它也可以用作消息队列。比如我们前面介绍 List 类型的时候说过,基于 LPUSH 和 BRPOP 可以实现一个简易版的消息队列,但它有两个缺点: 不支持多个消费者:消费者拉取消息后,这条消息就从 List 中删除了,无法被其它消费者再次消费,即不支持多个消费者消
阅读全文
摘要:楔子 我们前面介绍过 HyperLogLog 可以用来做基数统计,但它统计的是总数量,而无法判断某个指定的值是否存在。那我们如果想在海量数据之中检索某个值存在与否,该怎么做呢? 因为是海量数据,所以我们不可能将每个键值都存起来,然后再从结果中检索数据。我们只能依靠专门处理此问题的特殊方法来实现数据的
阅读全文
摘要:楔子 在使用 Redis 时,会面临缓存雪崩、缓存穿透、缓存击穿等问题,无论哪一个发生,都会导致大量请求打到数据库。如果数据库宕机,那就是很严重的事故了。 下面我们就来分析一下,这几个问题产生的原因以及解决办法。 缓存雪崩 缓存雪崩是指在短时间内,有大量缓存同时过期,导致大量请求直接查询数据库,从而
阅读全文
摘要:楔子 在使用 Redis 做缓存时,我们经常会遇到一些问题,比如: 缓存中的数据和数据库中的数据不一致; 缓存雪崩; 缓存穿透; 缓存击穿; 而且这些问题在面试的时候也几乎是必问,本文我们来探讨第一个问题,当缓存和数据库中的数据不一致的时候,该怎么办?因为数据不一致,那么从缓存当中就会获取到旧数据,
阅读全文
摘要:楔子 通过在后端服务和 MySQL 之间引入一层 Redis,可以极大地提升服务的响应速度。具体做法就是将数据放入 Redis 中,后续请求到来时,直接访问缓存,而不是数据库。那么问题来了,我们应该往缓存里放多少数据,如果 MySQL 存了 1T 的数据,难道这 1T 的数据都要放到缓存中吗?显然不
阅读全文
摘要:楔子 查询附近的人或者商家是一个非常常用并且实用的功能,比如:我们经常使用高德地图、百度地图或者其它地图,去查询想去的目的地在什么位置,并且还会显示距离。如果去的地方有多个,比如我们想去招商银行,但是附近有多个招商银行,那么地图会显示附近的所有银行,并默认按照距离进行排序,然后我们可以选择距离最近的
阅读全文
摘要:我们知道,如果想查询数据库中都有哪些 key 的话,可以使用 keys 命令。keys 后面接一个模式,即可返回所有匹配指定模式的 key。并且指定模式的时候,可以使用通配符,比如: *:匹配任意多个任意字符; ?:匹配单个任意字符; [...]:匹配 [] 中的任意一个字符; keys 这个命令很
阅读全文
摘要:楔子 在我们实际开发的过程中,可能会遇到这样一个问题,当我们需要统计不重复的元素个数时,应该用什么类型。举个简单的场景,统计大型网站每一天的 UV,注意是 UV(一个用户即使访问多次,也只能算作一次)。面对这个问题,你可能首先会想到使用集合,将用户的 IP 保存到集合中。由于集合内的元素是不重复的,
阅读全文
摘要:管道技术(Pipeline)是客户端提供的一种批处理技术,用于一次处理多个命令,从而提高整个交互的性能。 Redis 是单线程执行的,客户端先向服务端发送请求,服务端接收并处理请求、然后把结果返回给客户端,这种处理模式在非频繁请求时不会出现任何问题。 但如果出现集中的大批量请求时,因为每个请求都要经
阅读全文
摘要:楔子 Redis 也是有事务功能的,尽管它不像关系型数据库那样常用,但在面试的时候经常会被问到,下面我们就来总结一下 Redis 的事务。 通过 Redis 事务的原理以及实际操作,来彻底攻略 Redis 中的事务。 事务介绍 Redis 事务是一组命令的集合,将多个命令进行打包,然后这些命令会被顺
阅读全文
摘要:楔子 Redis 的配置非常多,加上注释的话,配置文件大概一两千行,里面有大量的配置可以供我们进行设置。其实关于 Redis 的配置我们之前也提到过,比如:开启多线程、设置线程数、数据结构内部存储元素的数量限制等等,那么下面我们就来介绍一下 Redis 配置文件中的一些其它的常见配置项。 配置文件
阅读全文
摘要:楔子 下面来解密 Redis 的有序集合,整篇文章分为三个部分。 Redis 有序集合的相关命令; Redis 有序集合的应用场景; Redis 有序集合的实现原理; Redis 有序集合的相关命令 Redis 的有序集合相比集合多了一个排序属性:score(分值),对于有序集合 ZSet 来说,每
阅读全文
摘要:楔子 下面来解密 Redis 的集合,整篇文章分为三个部分。 Redis 集合的相关命令; Redis 集合的应用场景; Redis 集合的实现原理; Redis 集合的相关命令 先来看看集合的相关命令,我们首先要学会如何使用它。 sadd key value1 value2 ···:向集合插入多个
阅读全文
摘要:楔子 下面来解密 Redis 的哈希,整篇文章分为三个部分。 Redis 哈希的相关命令; Redis 哈希的应用场景; Redis 哈希的实现原理; Redis 哈希的相关命令 hset key field1 value1 field2 value2···:设置键值对,可同时设置多个 这里的键值对
阅读全文
摘要:楔子 下面来解密 Redis 的列表,整篇文章分为三个部分。 Redis 列表的相关命令; Redis 列表的应用场景; Redis 列表的实现原理; Redis 列表的相关命令 先来看看列表的相关命令,我们首先要学会如何使用它。 lpush key value1 value2 ...:将多个值添加
阅读全文
摘要:楔子 下面来解密 Redis 的字符串,整篇文章分为三个部分。 Redis 字符串的相关命令; Redis 字符串的应用场景; Redis 字符串的实现原理; Redis 字符串的相关命令 先来看看字符串的相关命令,我们首先要学会如何使用它。 set key value:给指定的 key 设置 va
阅读全文
摘要:Redis 的数据类型可谓是 Redis 的精华所在,作为一款 QPS 能达到 10w 级别的内存数据库,具有如此高性能的原因有很多。除了所有的操作都在内存中进行之外,其数据类型的底层设计也起到了很大的作用。 我们知道 Redis 中有 5 种基础数据类型,分别是:String(字符串)、List(
阅读全文
摘要:Redis 是单线程还是多线程 Redis 应该是使用频率最高的组件之一了,不仅在工作中会大量使用,面试的时候也经常会作为考点出现,下面就来深入地了解一下 Redis。 先来探讨一个问题,Redis 使用的到底是多线程还是单线程? 不同版本的 Redis 是不同的,在 4.0 之前 Redis 是单
阅读全文
摘要:楔子 一个 SQL 语句写的好不好,评价的唯一标准就是它的时间,执行时间越短 SQL 写的就越好。所以 SQL 优化的目的,就是缩短 SQL 语句的执行时间。而基础以及日常的 SQL 优化方式就是设计好索引,让不太复杂的普通查询都用上索引。 但当表结构和我们写出来的 SQL 比较复杂时,比如包含各种
阅读全文
摘要:楔子 如果查询比较慢的话,大部分人应该都会说:"字段加索引了没?"。那么问题来了,索引到底是个什么东西呢,它为什么能够加快查询的速度呢,下面就来好好地聊一聊。 表的存储结构 介绍索引之前需要先来回顾一下表的存储结构,前面说过表在磁盘上会以一个 .ibd 文件的格式存在,而文件则由一个个数据页构成。所
阅读全文
摘要:楔子 本篇文章来聊一下 MySQL 的锁,首先不光是数据库,任何的一门高级语言也都内置了锁机制。从本质上讲,锁是一种协调多个进程或多个线程对某一资源进行访问的机制。而之所以要存在锁,是因为在并发编程中,程序的某一部分在并发访问的时候会导致意想不到的结果,所以这部分程序就需要用锁保护起来,而保护起来的
阅读全文
摘要:楔子 MySQL 的隔离级别默认采用的是可重复读(简称 RR),可以避免脏写、脏读、不可重复读,一个事务在查询的过程中,即使别的事务将值修改了,该事务查询到的结果也是不变的。 那么这是怎么实现的呢?下面来解答一下。 undo log 版本链 先给出结论,RR 是使用 MVCC(多版本并发控制)实现的
阅读全文
摘要:楔子 本次来聊一聊事务,首先事务一般指的是逻辑上的一组操作,或者作为单个逻辑单元执行的一系列操作。同属于一个事务的操作会作为一个整体提交给系统,这些操作要么全部执行成功,要么全部执行失败。 下面就简单地介绍一下事务的特性。 事务的特性 总体来说,事务存在四大特性,分别是原子性(Atomic)、一致性
阅读全文
摘要:undo log 回滚原理 前面介绍了 redo log,有了它便可以保证事务在提交之后数据不丢失。但是问题来了,如果事务执行到一半的时候需要回滚怎么办?比如一个事务里面有 4 个增删改语句,已经执行完两个了,Buffer Pool 的数据也被更新了,但是还有两个没有执行,而此时事务要回滚了,怎么办
阅读全文
摘要:redo log 如何保证数据不丢失 在介绍 Buffer Pool 的时候说到,MySQL 的增加改查操作都是在 Buffer Pool 里面进行的,比如更新数据,实际上就是更新 Buffer Pool 里面的缓存页。并且在更新缓存页的时候,还会更新 free 链表、flush 链表、LRU 链表
阅读全文
摘要:楔子 上一篇文章我们介绍了Buffer Pool,当时在文章里提到了表空间、区、数据页、一个区中的连续数据页,以及数据页号等等,这些概念可能让人一头雾水,本篇文章就来详细探讨一下。 首先上面这些概念当中,有一个我们是熟悉的,那就是数据页。每一行数据都放在数据页里面,一个数据页大小是 16KB,可以包
阅读全文
摘要:楔子 我们前面介绍了 Buffer Pool,它本质上就是一片内存,里面存储了 MySQL 的表数据。并且这片内存是可配置的,因为它不可能无限大,默认是 128MB。但很明显,在线上环境 128MB 有点小了,如果你的机器是 16GB 内存,或者更高,那么可以将它设置成 2GB。 [server]
阅读全文
摘要:楔子 上一篇文章我们介绍了 MySQL 的基本架构,这里再来回顾一下。 整个架构还是很好理解的,我们说 MySQL 分为 Server 层和存储引擎层。其中 Server 层包含了 MySQL 的大多数核心服务功能,而存储引擎层则负责提供数据的存储和读取,并且是插件式的,一个 Server 层支持不
阅读全文
摘要:Pthon 是怎么和 MySQL 交互的 假设你现在要用 Python 开发一个书籍管理系统,让管理员能够对 MySQL 数据库中的书籍信息进行增删改查,那么你会怎么做呢?其实很简单,使用 Web 框架编写一个服务,提供好相应的 API,当请求到来时,根据请求类型和参数拼接 SQL 语句,然后交给
阅读全文
摘要:初识 Flink 与流计算 Flink 在大数据领域已经应用的越来越广泛,很多大公司内部都有它的身影,那么问题来了,Flink 到底是用来做什么的呢? 首先提到 Flink 必然绕不开流计算(或者说流式计算、流处理等等),因为 Flink 是一个分布式、高性能的流计算引擎。比如天猫的成交额一分钟能破
阅读全文