我是Docker的新手,所以很可能,我错过了一些东西.
我使用这个image运行Elasticsearch的容器.
我能够正确设置每个人.之后,我使用了一个由同事开发的脚本来插入一些数据,基本上是查询MySQL数据库并发出HTTP请求.
问题是,许多请求在失败之前就会被卡住.如果我做netstat -tn | grep 9200我得到:
tcp6 0 0 ::1:58436 ::1:9200 TIME_WAIT
tcp6 0 0 ::1:59274 ::1:9200 TIME_WAIT
...
tcp6 0 0 ::1:58436 ::1:9200 TIME_WAIT
tcp6 0 0 ::1:59274 ::1:9200 TIME_WAIT
有很多要求.在这一点上,我不确定它是否与弹性搜索或码头有关.如果Elasticsearch在我的机器上是instaleld,则不会发生这种情况.
一些信息:
$docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7c8fca2
OS/Arch (client): linux/amd64
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7c8fca2
OS/Arch (server): linux/amd64
$docker info
Containers: 6
Images: 103
Storage Driver: devicemapper
Pool Name: docker-252:1-9188072-pool
Pool Blocksize: 65.54 kB
Backing Filesystem: extfs
Data file: /dev/loop0
Metadata file: /dev/loop1
Data Space Used: 4.255 GB
Data Space Total: 107.4 GB
Data Space Available: 103.1 GB
Metadata Space Used: 6.758 MB
Metadata Space Total: 2.147 GB
Metadata Space Available: 2.141 GB
Udev Sync Supported: false
Data loop file: /var/lib/docker/devicemapper/devicemapper/data
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
Library Version: 1.02.82-git (2013-10-04)
Execution Driver: native-0.2
Kernel Version: 3.14.22-031422-generic
Operating System: Ubuntu 14.04.2 LTS
CPUs: 4
Total Memory: 15.37 GiB
$docker logs elasticsearch
[2015-06-15 09:10:33,761][INFO ][node ] [Energizer] version[1.6.0], pid[1], build[cdd3ac4/2015-06-09T13:36:34Z]
[2015-06-15 09:10:33,762][INFO ][node ] [Energizer] initializing ...
[2015-06-15 09:10:33,766][INFO ][plugins ] [Energizer] loaded [], sites []
[2015-06-15 09:10:33,792][INFO ][env ] [Energizer] using [1] data paths, mounts [[/usr/share/elasticsearch/data (/dev/mapper/ubuntu--vg-root)]], net usable_space [145.3gb], net total_space [204.3gb], types [ext4]
[2015-06-15 09:10:35,516][INFO ][node ] [Energizer] initialized
[2015-06-15 09:10:35,516][INFO ][node ] [Energizer] starting ...
[2015-06-15 09:10:35,642][INFO ][transport ] [Energizer] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/172.17.0.5:9300]}
[2015-06-15 09:10:35,657][INFO ][discovery ] [Energizer] elasticsearch/Y1zfiri4QO21zRhcI-bTXA
[2015-06-15 09:10:39,426][INFO ][cluster.service ] [Energizer] new_master [Energizer][Y1zfiri4QO21zRhcI-bTXA][76dea3e6d424][inet[/172.17.0.5:9300]], reason: zen-disco-join (elected_as_master)
[2015-06-15 09:10:39,446][INFO ][http ] [Energizer] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/172.17.0.5:9200]}
[2015-06-15 09:10:39,446][INFO ][node ] [Energizer] started
[2015-06-15 09:10:39,479][INFO ][gateway ] [Energizer] recovered [0] indices into cluster_state
脚本的重要部分:
for package in c.fetchall():
id_package, tracking_number, order_number, payment_info, shipment_provider_name, package_status_name=package
el['tracking_number'] = tracking_number
el['order_number'] = order_number
el['payment_info'] = payment_info
el['shipment_provider_name'] = shipment_provider_name
el['package_status_name'] = package_status_name
requests.put("http://localhost:9200/packages/package/%s/_create"%(id_package), json=el)
最佳答案 所以,它不是Docker或Elastic的问题.回顾一下,在Elasticsearch安装程序中抛出PUT请求的同一个脚本在本地工作,但是在几千个文档(20k)之后抛出Elasticsearch的容器时失败了.要注意的是,大量文件的数量是800k.
那么,发生了什么?当你在localhost上运行somethig并向它发出请求(在这种情况下是一个PUT请求)时,该请求将通过loopback接口.在实践中,这意味着没有创建TCP连接使得更快.
设置docker容器后,端口绑定到主机.虽然脚本仍然在所需端口上向localhost发出请求,但是通过docker0接口在主机和docker容器之间创建了TCP连接.这是以牺牲两件事为代价的:
>设置TCP连接的时间
> TIME_WAIT状态
这实际上是一个更现实的场景.我们在另一台机器上设置了Elasticsearch并进行了完全相同的测试,并按预期得到了相同的结果.
问题是我们发送请求并为每个请求创建新连接.由于TCP的工作方式,连接不能立即关闭.这意味着我们使用所有可用的连接,直到我们没有使用,因为创建率高于实际收盘率.
三个建议来解决这个问题:
>每隔一段时间暂停请求.也许在每个X请求中都会睡眠,使TIME_WAIT可以通过并关闭连接
>发送Connection:close header:选项,发送方在完成响应后发出连接将被关闭的信号.
>重用连接.
我最终选择了3)并重写了我的同事的脚本并重用了相同的TCP连接.