Windows10系统下使用Docker搭建ClickHouse开发环境

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 随着现在业务开展,几个业务系统的数据量开始急剧膨胀。之前使用了关系型数据库MySQL进行了一次数据仓库的建模,发现了数据量上来后,大量的JOIN操作在提高了云MySQL的配置后依然有点吃不消,加之开发了一个基于关系型数据库设计的标签服务,日全量标签数据(无法避免的笛卡尔积)单表超过5000W。目前采取了基于用户ID分段配合多进程处理的方式暂时延缓了性能的恶化,但是还是需要做一个小型的数据平台。Hadoop的那套体系过于庞大,组件过多,硬件和软件的学习成本比较高,不是一朝一夕可以让小团队的所有成员掌握。考虑到这么多因素的前提下,需要调用ClickHouse这项黑科技,看看使用他能不能突围困局。

前提



随着现在业务开展,几个业务系统的数据量开始急剧膨胀。之前使用了关系型数据库MySQL进行了一次数据仓库的建模,发现了数据量上来后,大量的JOIN操作在提高了云MySQL的配置后依然有点吃不消,加之开发了一个基于关系型数据库设计的标签服务,日全量标签数据(无法避免的笛卡尔积)单表超过5000W。目前采取了基于用户ID分段配合多进程处理的方式暂时延缓了性能的恶化,但是考虑到不远将来,还是需要做一个小型的数据平台。Hadoop的那套体系过于庞大,组件过多,硬件和软件的学习成本比较高,不是一朝一夕可以让小团队的所有成员掌握。考虑到这么多因素的前提下,需要调用ClickHouse这项黑科技,看看使用他能不能突围困局。


微信截图_20220513175807.png


软件版本



这里就不对ClickHouse进行简介,其官方网站https://clickhouse.tech有详细的文档。一般使用Windows系统进行开发,如果是Windows10则可以直接安装Docker,利用Hyper-V的特性直接运行ClickHouse的镜像即可。下面列出开发环境搭建需要的软件:


软件 版本 备注
Windows 10 确保使用了Windows10并且开启了Hyper-V才能使用Docker
Docker Desktop 任意 DockerWindows桌面版
ClickHouse Server 20.3.x 直接拉取latest的镜像即可
ClickHouse Client 20.3.x 直接拉取latest的镜像即可
Cmder 最新版 可选,用来代替自带的不好用控制台


Windows10下可以通过:控制面板 -> 程序 -> 启用或关闭Windows功能 ->Hyper-V(勾选Hyper-V管理平台和Hyper-V平台,然后重启生效)开启Hyper-V特性:


微信截图_20220513175816.png


然后在Docker官方站点的https://www.docker.com/get-started子页面可以找到Docker Desktop的下载入口:


微信截图_20220513175824.png


安装完之后Docker Desktop会随着系统自启,软件界面如下:


微信截图_20220513175832.png


安装和使用ClickHouse



注意需要先初步了解ClickHouse的核心目录,再进行容器安装启动。


镜像拉取和核心目录


先下载ClickHouse ServerClickHouse Client的镜像:


docker pull yandex/clickhouse-server
docker pull yandex/clickhouse-client
复制代码


下载完毕后提示如下:


微信截图_20220513175840.png


可以通过docker images验证一下:


λ  docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
yandex/clickhouse-server   latest              c85f84ea6550        10 days ago         515MB
yandex/clickhouse-client   latest              f94470cc9cd9        10 days ago         488MB
复制代码


两个镜像其实都是包裹在一个微型的Ubuntu系统中,所以启动后的容器可以使用当作是一个Linux系统这样操作。ClickHouse Server在容器中的核心目录部分如下:


  • /etc/clickhouse-server:这个是ClickHouse Server默认的配置文件目录,包括全局配置config.xml和用户配置users.xml等等。
  • /var/lib/clickhouse:这个是ClickHouse Server默认的数据存储目录。
  • /var/log/clickhouse-server:这个是ClickHouse Server默认的日志输出目录。


为了方便管理配置、查看数据和搜索日志,可以把上面这三个目录直接映射到宿主机的具体目录,笔者在本开发机做了如下的映射:


Docker容器目录 宿主机目录
/etc/clickhouse-server E:/Docker/images/clickhouse-server/single/conf
/var/lib/clickhouse E:/Docker/images/clickhouse-server/single/data
/var/log/clickhouse-server E:/Docker/images/clickhouse-server/single/log


ClickHouse Server启动前需要注意几点:


  • ClickHouse Server服务本身依赖三个端口,这三个端口的默认值是9000TCP协议)、8123HTTP协议)和9009(集群数据复制),映射到宿主机的时候尽可能一一对应,所以需要确保宿主机的这三个端口没有被占用,可以使用Docker的参数-p指定容器和宿主机的端口映射。
  • ClickHouse Server正常使用需要修改容器系统的文件句柄数量配置ulimit nofile,可以使用Docker参数--ulimit nofile=262144:262144指定文件句柄数。
  • 可以运用一个技巧,使用Docker--rm参数创建临时容器,先获取到/etc/clickhouse-server目录下配置文件,通过docker cp 容器目录 宿主机目录命令可以拷贝容器的配置文件到宿主机目录下,容器停止之后会被直接删除,这样就能保留宿主机的配置文件模板。


临时容器拷贝配置


先执行命令docker run --rm -d --name=temp-clickhouse-server yandex/clickhouse-server运行一个临时容器,成功后通过下面的命令拷贝容器的config.xmlusers.xml文件到宿主机:


  • docker cp temp-clickhouse-server:/etc/clickhouse-server/config.xml E:/Docker/images/clickhouse-server/single/conf/config.xml
  • docker cp temp-clickhouse-server:/etc/clickhouse-server/users.xml E:/Docker/images/clickhouse-server/single/conf/users.xml


这两个命令执行完毕后,可以看到宿主机的磁盘目录已经生成了config.xmlusers.xml,接着需要做几项配置:


  • 创建default账号的密码。
  • 创建一个新的root账号。
  • 开放客户端监听的Host,避免后面使用JDBC客户端或者ClickHouse Client的时候无法连接ClickHouse Server


通过docker exec -it temp-clickhouse-server /bin/bash命令进入临时容器,然后在临时容器中执行:


  • PASSWORD=$(base64 < /dev/urandom | head -c8); echo "default"; echo -n "default" | sha256sum | tr -d '-'
  • PASSWORD=$(base64 < /dev/urandom | head -c8); echo "root"; echo -n "root" | sha256sum | tr -d '-'


root@607c5abcc132:/# PASSWORD=$(base64 < /dev/urandom | head -c8); echo "default"; echo -n "default" | sha256sum | tr -d '-'
default
37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f
root@607c5abcc132:/# PASSWORD=$(base64 < /dev/urandom | head -c8); echo "root"; echo -n "root" | sha256sum | tr -d '-'
root
4813494d137e1631bba301d5acab6e7bb7aa74ce1185d456565ef51d737677b2
复制代码


这样就得到了default:defaultroot:root两个账号密码的SHA256摘要。修改宿主机上的users.xml文件:


微信截图_20220513175849.png


然后修改宿主机上的config.xml文件:


微信截图_20220513175856.png


最后通过docker stop temp-clickhouse-server停止和销毁临时容器。


运行ClickHouse服务


接着使用下面的命令创建和运行一个ClickHouse Server容器实例(确保config.xmlusers.xml已经存在):


命名和容器命名:docker run -d --name=single-clickhouse-server 
端口映射:-p 8123:8123 -p 9000:9000 -p 9009:9009 
文件句柄数配置:--ulimit nofile=262144:262144 
数据目录映射:-v E:/Docker/images/clickhouse-server/single/data:/var/lib/clickhouse:rw 
配置目录映射:-v E:/Docker/images/clickhouse-server/single/conf:/etc/clickhouse-server:rw 
日志目录映射:-v E:/Docker/images/clickhouse-server/single/log:/var/log/clickhouse-server:rw 
镜像:yandex/clickhouse-server
复制代码


上面的命令合成一行执行docker run -d --name=single-clickhouse-server -p 8123:8123 -p 9000:9000 -p 9009:9009 --ulimit nofile=262144:262144 -v E:/Docker/images/clickhouse-server/single/data:/var/lib/clickhouse:rw -v E:/Docker/images/clickhouse-server/single/conf:/etc/clickhouse-server:rw -v E:/Docker/images/clickhouse-server/single/log:/var/log/clickhouse-server:rw yandex/clickhouse-server


上面的命令执行完后,Docker Desktop会有几个弹出框确认是否共享宿主机的目录,直接按share it按钮即可。


微信截图_20220513175903.png


最后使用原生的命令行客户端ClickHouse Client进行连接,使用命令docker run -it --rm --link single-clickhouse-server:clickhouse-server yandex/clickhouse-client -uroot --password root --host clickhouse-server


λ  docker run -it --rm --link single-clickhouse-server:clickhouse-server yandex/clickhouse-client -uroot --password root --host clickhouse-server
ClickHouse client version 20.10.3.30 (official build).
Connecting to clickhouse-server:9000 as user root.
Connected to ClickHouse server version 20.10.3 revision 54441.
f5abc88ff7e4 :) select 1;
SELECT 1
┌─1─┐
│ 1 │
└───┘
1 rows in set. Elapsed: 0.004 sec.
复制代码


下次如果电脑重启ClickHouse Server的容器没有启动,只需要使用命令docker (re)start single-clickhouse-server拉起容器实例即可。


使用JDBC连接ClickHouse服务



ClickHouseJDBC驱动目前有三个:



说实话有点尴尬,官方的驱动包竟然没有对接TCP私有协议栈,而是使用了HTTP协议进行交互,这里不知道性能会下降多少,但是基于"官方更好"的思维这里还是选用官方的驱动包进行Demo演示。引入clickhouse-jdbc依赖:


<dependency>
    <groupId>ru.yandex.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.2.4</version>
</dependency>
复制代码


编写一个测试类:


public class ClickHouseTest {
    @Test
    public void testCh() throws Exception {
        ClickHouseProperties props = new ClickHouseProperties();
        props.setUser("root");
        props.setPassword("root");
        // 不创建数据库的时候会有有个全局default数据库
        ClickHouseDataSource dataSource = new ClickHouseDataSource("jdbc:clickhouse://localhost:8123/default", props);
        ClickHouseConnection connection = dataSource.getConnection();
        ClickHouseStatement statement = connection.createStatement();
        // 创建一张表,表引擎为Memory,这类表在服务重启后会自动删除
        boolean execute = statement.execute("CREATE TABLE IF NOT EXISTS t_test(id UInt64,name String) ENGINE  = Memory");
        if (execute) {
            System.out.println("创建表default.t_test成功");
        } else {
            System.out.println("表default.t_test已经存在");
        }
        ResultSet rs = statement.executeQuery("SHOW TABLES");
        List<String> tables = Lists.newArrayList();
        while (rs.next()) {
            tables.add(rs.getString(1));
        }
        System.out.println("default数据库中的表:" + tables);
        PreparedStatement ps = connection.prepareStatement("INSERT INTO t_test(*) VALUES (?,?),(?,?)");
        ps.setLong(1, 1L);
        ps.setString(2, "throwable");
        ps.setLong(3, 2L);
        ps.setString(4, "doge");
        ps.execute();
        statement = connection.createStatement();
        rs = statement.executeQuery("SELECT * FROM t_test");
        while (rs.next()) {
            System.out.println(String.format("查询结果,id:%s,name:%s", rs.getLong("id"), rs.getString("name")));
        }
    }
}
复制代码


执行结果如下:


表default.t_test已经存在   # <--- 这里估计是驱动包的实现有BUG,首次创建成功返回结果为false
default数据库中的表:[t_test]
查询结果,id:1,name:throwable
查询结果,id:2,name:doge
复制代码


小结



ClickHouse开发环境初步搭建完毕,后面会开始学习ClickHouse的基本语法、各类引擎的特性和使用场景以及集群搭建(分片和多副本)等等。


参考资料:


提醒



这个是笔者在某次直接断电后发现Docker中的ClickHouse服务虽然重启成功,但是错误日志疯狂输出File not found,导致所有客户端无法连接服务。初步判断为元数据和实际存储的数据因为"断电"后造成不一致导致的。所以建议在开发环境中关机前要先进入容器调用service clickhouse-server stop,然后在宿主机调用docker stop 容器名|容器ID停止容器再进行关机,否则需要递归删除数据目录下的store目录中的所有文件才能正常重启ClickHouse Server和使用(这个是十分粗暴的办法,有比较大几率会直接导致数据丢失,一定要谨慎操作)。


(本文完 c-2-d e-a-20201108 开始搞小数据)


相关文章
|
2月前
|
Linux 虚拟化 Docker
Windows10安装Docker Desktop(大妈看了都会)
Windows10安装Docker Desktop(大妈看了都会)
629 2
|
2月前
|
Java Shell Linux
入职必会-开发环境搭建49-Docker必会构建镜像
前面一直都是从Docker仓库中下载镜像然后使用。我们项目中可以通过Dockerfile构建自己的镜像。 Dockerfile是由一系列命令和参数构成的文本文件,Docker可以读取Dockerfile文件并根据Dockerfile文件的描述来构建镜像。Dockerfile文件内容一般分为4部分 ● 基础镜像信息 ● 维护者信息 ● 镜像操作指令 ● 容器启动时执行的指令
|
2月前
|
存储 Docker 容器
入职必会-开发环境搭建50-Docker必会搭建Docker私有仓库
Docker官方的Docker hub(https://hub.docker.com)是一个用于管理公共镜像的仓库,我们可以从上面拉取镜像到本地也可以把我们自己的镜像推送上去。但是有时候我们的服务器无法访问互联网或者不希望将自己的镜像放到公网当中,那么我们就需要搭建自己的Docker私有仓库来存储和管理自己的Docker镜像。
入职必会-开发环境搭建50-Docker必会搭建Docker私有仓库
|
2月前
|
关系型数据库 应用服务中间件 nginx
入职必会-开发环境搭建48-Docker必会软件安装
本文介绍了Docker安装MySQL,Docker安装Tomcat,Docker安装Nginx,Docker安装Redis
入职必会-开发环境搭建48-Docker必会软件安装
|
2月前
|
存储 Linux 应用服务中间件
入职必会-开发环境搭建47-Docker必会命令
本文介绍了Docker使用频率最高的30个命令
入职必会-开发环境搭建47-Docker必会命令
|
1月前
|
安全 开发者 Docker
使用Docker进行本地开发环境设置:高效、可重复与隔离的利器
【8月更文挑战第8天】使用Docker进行本地开发环境设置不仅提高了开发效率,还保证了开发环境的一致性和可重复性。通过简单的Dockerfile和Docker命令,开发者可以轻松地创建、运行和管理自己的开发环境。随着Docker的普及和生态的不断发展,相信它将在未来的软件开发中发挥更加重要的作用。
|
29天前
|
Linux 虚拟化 Docker
深入了解Windows安装Docker
【8月更文挑战第22天】深入了解Windows安装Docker
81 0
|
30天前
|
Java Linux Docker
【zookeeper 第二篇章】windows、linux、docker-compose 安装 zookeeper
本文介绍Zookeeper在不同环境下的安装方法。Linux安装需备好JDK,下载并解压Zookeeper后,复制`zoo_sample.cfg`为`zoo.cfg`,最后运行`zkServer.sh start`启动服务。Windows安装类似,通过`zkServer.bat`启动。使用Docker-Compose则需编写配置文件,并通过`docker-compose up -d`后台启动容器。
32 0
|
2月前
|
安全 Linux 持续交付
入职必会-开发环境搭建46-Docker下载和安装
Docker是一种开源的容器化平台,用于构建、部署和运行应用程序。它通过容器的方式将应用程序及其相关依赖项打包在一起,形成一个独立、可移植的运行环境。 以下是Docker的主要特点和优势。
|
1月前
|
Docker Windows 容器
Windows 2016 安装 Docker
Windows 2016 安装 Docker
13 0