使用 Python 驱动程序连接到 Dockerized Clickhouse Server 时出现问题

LoF*_*F10 5 python docker clickhouse

我在使用 python 驱动程序连接到 Windows docker 容器中的 clickhouse 时遇到问题。Clickhouse 服务器在我的 E 驱动器上的 Docker 容器中运行,暴露于端口 8123。我可以在 R 中使用此包轻松连接https://github.com/hannesmuehleisen/clickhouse-r,如下所示:

conn = DBI::dbConnect(clickhouse::clickhouse(), 
              host = "my_ip", 
              port = 8123L,
              user = "myun",
              password = "mypwd")
Run Code Online (Sandbox Code Playgroud)

但是当我使用https://clickhouse-driver.readthedocs.io/en/latest/quickstart.html在 python 中尝试同样的事情时,我遇到了一个问题:

from clickhouse_driver import Client
client = Client(host = 'my_ip',
                port = '8123',
                user='myun',
                password='mypwd',
                secure=True,
                verify=False,
                database='db_name')

print(client.execute('SELECT now()'))

File "d:\ProgramData\Anaconda3\lib\site-packages\clickhouse_driver\connection.py", line 249, in connect
    '{} ({})'.format(e.strerror, self.get_description())

NetworkError: Code: 210. [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:777) (my_ip:8123)
Run Code Online (Sandbox Code Playgroud)

有人知道可能是什么问题吗?

更新

尝试 secure = F 并得到:

  File "d:\ProgramData\Anaconda3\lib\site-packages\clickhouse_driver\connection.py", line 243, in connect
    '{} ({})'.format(e.strerror, self.get_description())

SocketTimeoutError: Code: 209. None
Run Code Online (Sandbox Code Playgroud)

vla*_*mir 6

让我们分别考虑不安全和安全通信:


TCP(非安全通信)

docker run -d -p 9000:9000 --ulimit nofile=262144:262144 yandex/clickhouse-server
Run Code Online (Sandbox Code Playgroud)
  • 应用程序代码
client = Client(host='localhost',
                port='9000', # this param can be missed because port 9000 is used by default
                # ..
                database='test')
Run Code Online (Sandbox Code Playgroud)

TCP(安全通信)

  • clickhouse-driver通过9440上的本机协议与 ClickHouse 服务器通信端口
  • docker 容器应将端口 9440 发布到主机
docker run -d -p 9440:9440 --ulimit nofile=262144:262144 yandex/clickhouse-server
Run Code Online (Sandbox Code Playgroud)
  • 配置ClickHouse

在容器上执行交互式bash -shell:

docker exec -it {CONTAINER_ID} bash
Run Code Online (Sandbox Code Playgroud)

在容器内进行所需的更改:

apt-get update

# modify config-file
apt-get install nano
# uncomment the '<tcp_port_secure>'-section in config-file & save changes
nano /etc/clickhouse-server/config.xml

# generate a self-signed certificate & 'dhparam.pem'-file
apt-get install openssl

openssl req -subj "/CN=my.host.name" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt

openssl dhparam -out /etc/clickhouse-server/dhparam.pem 512 # 4096

# set required access mode to 'server.key'-file
chmod 644 /etc/clickhouse-server/server.key

# exit from interactive mode
exit
Run Code Online (Sandbox Code Playgroud)

重启容器:

docker restart {CONTAINER_ID}
Run Code Online (Sandbox Code Playgroud)
  • 应用程序代码
client = Client(host='localhost',
                port='9440', # this param can be missed because port 9440 is used by default
                secure=True,
                verify=False,
                # ..
                database='test')
Run Code Online (Sandbox Code Playgroud)

评论:

  • Docker 容器内的 SSL 手动配置仅用于测试。最好挂载所需的 SSL 文件和config.xml挂载到容器或创建具有所需更改的自定义 Docker 映像
  • 请参阅Altinity - ClickHouse Networking,第 2部分 - 文章深入了解 SSL 配置


小智 3

ClickHouse 服务器和客户端之间的通信有两种协议:http(端口 8123)和 Native(端口 9000)。

Http适用于curl/wget等工具。大多数 ClickHouse 客户端使用 http 进行数据传输。在你的情况下包括R。但有些客户端使用本机协议(go,以及这个 python 客户端)。该协议应该比 http 更有效。https://clickhouse-driver.readthedocs.io/en/latest/#user-s-guide

从服务器容器公开端口 9000 并在客户端中使用它。该端口也是该客户端的默认端口。