Docker安装ClickHouse22.6.9.11并与SpringBoot、MyBatisPlus集成

背景

上一篇文章CentOS6.10上离线安装ClickHouse19.9.5.36并修改默认数据存储目录记录了在旧版的操作系统上直接安装低版本 ClickHouse (脱胎于俄罗斯头号搜索引擎的技术)的过程,开启远程访问并配置密码;

其实通过 Docker 运行 ClickHouse 是我在2022年10月左右在虚拟机上实验的,当时 DockerHub 还可以打开,现在需要更换国内镜像才可以。。这里记录下当时使用 Docker 运行 ClickHouse 的过程。

2023-06-10-ClickHouse.jpg

Docker 镜像仓库 DockerHub 地址(正常情况下,已无法访问。。可参考文末链接自行配置): https://hub.docker.com/r/clickhouse/clickhouse-server

系统环境

[root@clickhouse1 local]# uname -a
Linux clickhouse1 3.10.0-1127.el7.x86_64 #1 SMP Tue Mar 31 23:36:51 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@clickhouse1 local]# cat /proc/version
Linux version 3.10.0-1127.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Mar 31 23:36:51 UTC 2020
[root@clickhouse1 local]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)

启动运行

根据容器镜像文档中的说明,一键启动 ClickHouse 服务。

docker run -d \
	-p 8123:8123 -p9000:9000 -p9009:9009 --privileged \
	-v /opt/clickhouse/data:/var/lib/clickhouse/ \
	-v /opt/clickhouse/logs:/var/log/clickhouse-server/ \
	--name heartsuit-clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server:22.6.9.11

# 容器成功运行
[root@clickhouse1 ~]# docker ps
CONTAINER ID   IMAGE                                    COMMAND            CREATED              STATUS              PORTS                                                                                                                             NAMES
f1474927f130   clickhouse/clickhouse-server:22.6.9.11   "/entrypoint.sh"   About a minute ago   Up About a minute   0.0.0.0:8123->8123/tcp, :::8123->8123/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp, 0.0.0.0:9009->9009/tcp, :::9009->9009/tcp   heartsuit-clickhouse-server

# 验证服务OK
[root@clickhouse1 ~]# curl 192.168.44.148:8123
Ok.

用于管理 Docker 和防火墙的命令。

systemctl start docker
systemctl status docker

systemctl stop firewalld
systemctl disable firewalld

初步体验

这个版本的 ClickHouse 有个 PlayGround 端点: http://IP:8123/play ,可以直接通过 Web 的方式与 OLAP 数据库进行交互查询;

浏览器访问: http://192.168.44.148:8123/play ,快速体验下,建库、建表、查询等操作用起来跟 MySQL 差不多。

show databases;

CREATE DATABASE IF NOT EXISTS helloworld;

show databases;

CREATE TABLE helloworld.my_first_table
(
    user_id UInt32,
    message String,
    timestamp DateTime,
    metric Float32
)
ENGINE = MergeTree()
PRIMARY KEY (user_id, timestamp);

INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES
    (101, 'Hello, ClickHouse!',                                 now(),       -1.0    ),
    (102, 'Insert a lot of rows per batch',                     yesterday(), 1.41421 ),
    (102, 'Sort your data based on your commonly-used queries', today(),     2.718   ),
    (101, 'Granules are the smallest chunks of data read',      now() + 5,   3.14159 )

SELECT * FROM helloworld.my_first_table;

SELECT * FROM helloworld.my_first_table ORDER BY timestamp;

SELECT * FROM helloworld.my_first_table ORDER BY timestamp FORMAT TabSeparated;

通过CSV写入数据表

# 新建data.csv,写入逗号分隔的以下内容
vi data.csv

102,This is data in a file,2022-02-22 10:43:28,123.45
101,It is comma-separated,2022-02-23 00:00:00,456.78
103,Use FORMAT to specify the format,2022-02-21 10:43:30,678.90

# 向docker容器内传文件
docker cp data.csv heartsuit-clickhouse-server:/

docker ps

# 进入容器内部
docker exec -it heartsuit-clickhouse-server /bin/bash

# 指定目录启动ClickHouse命令行客户端,导入csv文件
clickhouse-client \
> --query='INSERT INTO helloworld.my_first_table FORMAT CSV' < data.csv

# 验证导入结果
SELECT * FROM helloworld.my_first_table

Note:默认情况下,用户名默认为:default,密码为空;实际生产环境下如果需要开启远程访问,建议配置密码,可参考:CentOS6.10上离线安装ClickHouse19.9.5.36并修改默认数据存储目录

可能遇到的问题

如果关闭防火墙后没有重启 Docker ,运行容器时就会遇到下面的错误信息。

Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-af6aa0eafdec -j RETURN: iptables: No chain/target/match by that name.

SpringBoot集成ClickHouse与MyBatisPlus

新建 SpringBoot 项目,常规操作,在依赖中选择 Web , Lombok , 附加 MyBatis Plus

核心依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--ClickHouse 依赖-->
        <dependency>
            <groupId>ru.yandex.clickhouse</groupId>
            <artifactId>clickhouse-jdbc</artifactId>
            <version>0.1.53</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

配置文件

mybatis-plus:
  configuration:
    # 开启下划线转驼峰
    map-underscore-to-camel-case: true
    # 指定默认枚举类型的类型转换器
    default-enum-type-handler: com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    banner: false
    db-config:
      # 逻辑删除(软删除)
      logic-delete-value: NOW()
      logic-not-delete-value: 'NULL'
  mapper-locations: classpath:mapper/*.xml

spring:
  datasource:
    driver-class-name: ru.yandex.clickhouse.ClickHouseDriver
    url: jdbc:clickhouse://IP:8123/poetry
    username: default
    password: CK666%

核心代码

通过集成 MyBatis PlusServiceMapper 分别继承 IServiceBaseMapper ,不贴代码了,具体见文末 GitHub 源码。

  • 实体类

源自诗词数据库的31万多首诗词。表 poetry 结构如下,数据量:311828。

CREATE TABLE `poetry` (
	`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
	`title` VARCHAR(150) NOT NULL COLLATE 'utf8mb4_unicode_ci',
	`yunlv_rule` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci',
	`author_id` INT(10) UNSIGNED NOT NULL,
	`content` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci',
	`dynasty` VARCHAR(10) NOT NULL COMMENT '诗所属朝代(S-宋代, T-唐代)' COLLATE 'utf8mb4_unicode_ci',
	`author` VARCHAR(150) NOT NULL COLLATE 'utf8mb4_unicode_ci',
	PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=311829;
@Data
public class Poetry {
    @TableId
    private Integer id;
    private Integer authorId;
    private String title;
    private String content;
    private String yunlvRule;
    private String author;
    private char dynasty;
}
  • 控制器

分别写了接口测试 ClickHouse 数据库的:列表查询、条件查询、分页查询、新增、修改、删除功能(这里在测试修改、删除功能时遇到了问题:与 MyBatis Plus 中通用的修改、删除语句不同,最后通过扩展 MyBatis Plus 源码实现了根据实体 ID 修改和删除的功能)。

2023-06-10-RestAPI.jpg

@RestController
public class PoetryController {
    @Autowired
    private PoetryService poetryService;

    @Autowired
    private PoetryMapper poetryMapper; // 调用扩展方法

    @GetMapping("list")
    private List<Poetry> list() {
        return poetryService.list(new QueryWrapper<Poetry>().last("limit 10"));
    }

    @GetMapping("condition")
    private List<Poetry> listByCondition() {
        LambdaQueryWrapper<Poetry> wrapper = new QueryWrapper<Poetry>().lambda().eq(Poetry::getAuthor, "顾城");
        return poetryService.list(wrapper);
    }

    @GetMapping("page")
    private IPage<Poetry> listByPage(@RequestParam(defaultValue = "0") Integer page,
                                     @RequestParam(defaultValue = "2") Integer size) {
        return poetryMapper.selectPage(new Page<>(page, size), null);
    }

    @PostMapping("save")
    public boolean save() {
        Poetry poetry = new Poetry();
        poetry.setId(400000); // 如果ClickHouse中没有设置ID自增,需要显式赋值
        poetry.setAuthorId(20000);
        poetry.setTitle("一代人");
        poetry.setContent("黑夜给了我黑色的眼睛,我却用它寻找光明");
        poetry.setYunlvRule("balabala");
        poetry.setDynasty('Z');
        poetry.setAuthor("顾城");

        return poetryService.save(poetry);
    }

    // Update和Delete语句在ClickHouse中报错,ClickHouse的修改和删除SQL操作与MySQL不同。
    // 参考解决:https://github.com/saimen90/clickhouse
    @PutMapping("update/{id}")
    public boolean update(@PathVariable Integer id) {
        Poetry poetry = poetryService.getById(id);
        poetry.setYunlvRule("wow");
        return poetryMapper.updateByIdClickHouse(poetry); // 扩展方法
    }

//    报错!!需要扩展MyBatis源码
//    @PutMapping("update")
//    public boolean updateByCondition() {
//        UpdateWrapper<Poetry> updateWrapper = new UpdateWrapper<>();
//        return poetryService.update(updateWrapper.lambda().set(Poetry::getDynasty, "C").eq(Poetry::getId, 40000));
//    }

    @DeleteMapping("delete/{id}")
    public boolean deleteById(@PathVariable Integer id) {
        // 删除成功或失败,count都为0。。
        int count = poetryMapper.deleteByIdClickHouse(id); // 扩展方法
        return count > 0;
    }
}

扩展MyBatisPlus源码

核心代码在 com/heartsuit/infrastructure 路径下,主要参考了https://github.com/saimen90/clickhouse。

2023-06-10-ExtendMyBatisPlus.jpg

此外,新建 SupperMapper.java 接口,然后让实体的 Mapper 接口继承 SuperMapper

public interface SuperMapper<T> extends BaseMapper<T> {

    /**
     * @return
     * @Description: 删除并填充删除人信息
     * @param: id 主键id
     * @auther: zpq
     * @date: 2020/11/10 11:47 上午
     */
    boolean updateByIdClickHouse(@Param("et") T entity);

    /**
     * @return
     * @Description: 删除并填充删除人信息
     * @param: id 主键id
     * @auther: zpq
     * @date: 2020/11/10 11:47 上午
     */
    boolean updateClickHouse(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

    /**
     * 主键删除
     *
     * @param id
     * @return
     */
    int deleteByIdClickHouse(Serializable id);
}

Source Code

  • Source Code: Github

Reference

  • https://github.com/saimen90/clickhouse
  • docker镜像仓库hub.docker.com无法访问

If you have any questions or any bugs are found, please feel free to contact me.

Your comments and suggestions are welcome!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/28513.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ESXi 7.0 U3m Cisco (思科) 定制版 OEM Custom Installer CD

VMware ESXi 7.0 Update 3m - 领先的裸机 Hypervisor (All OEM Customized Installer CDs) ESXi 7.0 U3m Standard (标准版) ESXi 7.0 U3m Dell (戴尔) 定制版 OEM Custom Installer CD ESXi 7.0 U3m HPE (慧与) 定制版 OEM Custom Installer CD ESXi 7.0 U3m Lenovo (联想) 定…

6个ChatGPT4的最佳用途

文章目录 ChatGPT 4’s Current Limitations ChatGPT 4 的当前限制1. Crafting Complex Prompts 制作复杂的提示2. Logic Problems 逻辑问题3. Verifying GPT 3.5 Text 验证 GPT 3.5 文本4. Complex Coding 复杂编码5.Nuanced Text Transformation 细微的文本转换6. Complex Kn…

提高你的小程序开发技能:五大重要步骤

对于任何开发人员来说&#xff0c;想要创建一个小程序并不是一件容易的事情。你需要为每个功能和应用程序编写代码&#xff0c;并且你需要不断地进行测试以确保它不会出错。 那么&#xff0c;我们该如何提高小程序的开发技能呢&#xff1f;通过下面这五个重要步骤&#xff0c;…

盖茨预言AI助理成标配,AI+RPA打破AI准入高门槛!

根据微软联合创始人比尔盖茨的预测&#xff0c;未来顶级的人工智能公司将会开发一种全新的“个人AI助理”。比尔盖茨表示&#xff0c;“个人AI助理”将会具有出色的功能&#xff0c;可以改变人们的生活方式以及工作方式。无论哪一家公司能够赢得AI助理竞争先机&#xff0c;都会…

ZipList(压缩链表)

基本概述 ZipList 是一种特殊的“双端链表” &#xff0c;由一系列特殊编码的连续内存块组成。可以在任意一端进行压入/弹出操作, 并且该操作的时间复杂度为 O(1)。 基本结构&#xff1a; 各部分所占字节、基本介绍&#xff1a; entry&#xff0c;节点占用字节不固定&#xff0…

Mind2Web: 首个全面衡量大模型上网能力的数据集

夕小瑶科技说 原创 作者 | 智商掉了一地、ZenMoore 在互联网的浩瀚世界中&#xff0c;存在着无数复杂而扑朔迷离的任务等待我们去解决。如果要设计一个解决很多问题的通用智能体&#xff08;AI agent&#xff09;&#xff0c;无论是关于购物、旅行、学习还是娱乐&#xff0c;…

MySQL高级篇第二天

文章目录 一、Mysql的体系结构概览 二、 存储引擎 三、优化SQL步骤 一、Mysql的体系结构概览 整个MySQL Server由以下组成 Connection Pool : 连接池组件 Management Services & Utilities : 管理服务和工具组件 SQL Interface : SQL接口组件 Parser : 查询分析器组件 O…

感觉被榨干了,被美团拷打一小时...

普通本科毕业后&#xff0c;进了一家互联网公司&#xff0c;这几年里不断在积累经验&#xff0c;最终选择跳到美团&#xff0c;涨薪了50%&#xff0c;下面分享一下我个人的面经和一些心得建议。 面经 面团一面 自我介绍专业技能一条条核对下来 有软件测试流程、用例设计方法…

快速入门教程:神经常微分方程 (Neural ODE)

神经常微分方程(Neural Ordinary Differential Equations,简称 Neural ODE)是一种基于常微分方程(Ordinary Differential Equations,ODEs)的深度学习方法,它结合了传统的ODE数值求解技术和神经网络模型。通过使用ODE来建模数据的演化过程,Neural ODE可以自动地学习数据…

力扣题库刷题笔记3--无重复字符的最长子串

1、题目如下&#xff1a; 2、个人Python代码实现如下&#xff1a; 代码如下&#xff1a; class Solution: def lengthOfLongestSubstring(self, s: str) -> int: temp "" #临时变量&#xff0c;记录当前连续不重复子串 out_put …

中国市场成为高阶智驾战略高地,博世/安波福包揽四项大奖

高工智能汽车研究院监测数据显示&#xff0c;2022年度中国市场&#xff08;不含进出口&#xff09;乘用车前装标配搭载辅助驾驶&#xff08;L0-L2&#xff09;交付1001.22万辆&#xff0c;首次突破千万辆规模&#xff0c;同时&#xff0c;前装搭载率也首次突破50%大关。 此外&a…

我用AI提高我的代码质量,周边同事对我的代码赞不绝口,速来围观

文章目录 前言功能演示1.使用Stream API来简化集合操作2.使用switch语句来替代多个if-else语句3.使用try-with-resources语句来自动关闭资源4. Lambda 表达式来简化代码,并提高代码的可读性和可维护性5.查找代码中的bug并优化6.python 使用sort方法来对列表进行排序7.javaScrpi…

【docker桌面版】windows使用docker搭建nginx

1.拉取nginx镜像 docker pull nginx 2.运行容器 docker run -d -p 80:8081 --name nginx nginx 3.本地磁盘创建nginx目录 D:\Docker\project\nginx 4.复制docker中的nginx配置文件 查看运行的容器docker ps -a docker cp 8f18d58bc77b:/etc/nginx/nginx.conf D:\Docker…

docker ansible与剧本模式

ansible&#xff08;跨主机编排&#xff09; ansible 是一个基于python开发的配置管理和应用部署和管理工具&#xff0c;现在也在自动化管理领域大放异彩&#xff0c;他融合了众多老牌运维工具的优点&#xff0c;pubbet和saltstack能实现的功能&#xff0c;ansible基本上都可以…

Docker使用记录

文章目录 Docker基本使用Docker配置查看状态卸载安装使用 apt 存储库安装在 Ubuntu 上安装 Docker 桌面(非必要) Docker实例使用现有的镜像查找镜像拖取镜像列出镜像列表更新镜像导出镜像删除镜像导入镜像清理镜像查看容器导出容器导入容器-以镜像的方式创建容器重启容器进入容…

虚函数表不一定总是在对象的起始位置

在我之前的一篇文章 “COM 对象的内存布局”中&#xff0c;作为举例&#xff0c;我将对象的虚函数表指针放置在了底层 C 对象的起始位置&#xff0c;但是值得注意的是&#xff0c;虚函数表指针指向的位置并没有一个实际的标准。即使将虚函数表放置在对象中间&#xff0c;甚至是…

零基础想转行做python爬虫及数据分析方向的程序员,有哪些书可以推荐?

学习Python语言是一个不错的选择&#xff0c;一方面Python的应用广泛&#xff0c;在大数据、人工智能、Web开发等领域有大量的使用&#xff0c;另一方面Python语言本身比较简单&#xff0c;非常适合初学者。 Python是完全可以自学的&#xff0c;如果英语基础还可以的话&#x…

Maxwell安装使用

​欢迎光临我的博客查看最新文章: https://river106.cn 1、Maxwell简介 Maxwell 是由美国Zendesk开源&#xff0c;用Java编写的MySQL实时抓取软件。读取 MySQL binlogs 并将修改行字段的更新写入 Kafka, Kinesis, RabbitMQ, Google Cloud Pub/Sub 或 Redis (Pub/Sub or LPUSH)…

3. SpringCloudAlibaba、nacos 实现配置中心

一、微服务中配置文件的问题 1.1 配置文件的问题&#xff1a; 配置文件的数量会随着服务的增加持续递增单个配置文件无法区分多个运行环境配置文件内容无法动态更新&#xff0c;需要重启服务 1.2 引入配置中心 引入配置中心&#xff1a;刚才架构就会成为这样。是由配置中心统…

2023上半年的九个觉悟

‍觉悟&#xff0c;就是觉了、悟了。有时候&#xff0c;你看到一句话&#xff0c;突然就觉悟了。 一、资本主义的问题 “资本主义把我们都缩减成了一个东西&#xff1a;消费者” 因此&#xff0c;人人都成为资本家利诱、操控、围猎的对象。 同时&#xff0c;金钱成为全民的神&a…