写在前面
近日网上各论坛,Q 群对于 QQ 8 亿数据、微博 5 亿数据讨论的很多,不管有没有用,很多人都把数据下载下来了。但对于庞大的数据,却又不知道怎么用。就算是在 EmEditor (超大文件编辑器)中打开查询起来也非常慢,这里简单给大家分享一下方法。
准备一台 Linux 系统的机器,用来存储数据硬盘需要比较大一些,硬盘 100G 以上。也可以购买公有云的 ES 服务,比如腾讯云有一款新用户免费 30 天的试用款,可以直接买来测试学习。
再准备一台 Linux 系统的机器,用来将数据处理写入到存储机上,当然你两台放一起也可以,性能可能没有两台好。
其次要保证,两台机器之间的网络速度要通畅,尽可能的在这方面减少损耗。
※ 因仅用于技术交流分享,本文不提供资源文件下载。
※ 因仅用于技术交流分享,本文不提供任何现成脚本文件。
安装 Elasticsearch
首先从官网下载 Linux,在存储机上安装 ES.
安装路径为:/usr/local/elasticsearch
存储路径为:/mnt/hd1/es
没有则先创建:
mkdir /mnt/hd1/es/data -p
mkdir /mnt/hd1/es/logs -p
下载解压 elasticsearch
cd /usr/local
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-linux-x86_64.tar.gz
tar -xzf elasticsearch-7.10.1-linux-x86_64.tar.gz
mv elasticsearch-* elasticsearch
cd elasticsearch
执行用户
elasticsearch 执行需要在非 root 用户上,这里创建一个低级权限用户名为 es:
useradd es
虚拟内存
如果你在内存非常小的机器上试用时,ES 需要相对大点的内存,比如 2G 以上。你就不得不开启 swap 虚拟交换内存,在此忽略此项。
如果物理内存满足的情况下,建议直接关闭 swap ,避免影响 es 的的性能处理速度。
swapoff -a
max_map_count
根据官方推荐,我们优化 max_map_count 参数 (https://www.elastic.co/guide/cn/elasticsearch/guide/current/_file_descriptors_and_mmap.html)
Elasticsearch 对各种文件混合使用了 NioFs( 注:非阻塞文件系统)和 MMapFs ( 注:内存映射文件系统)。请确保你配置的最大映射数量,以便有足够的虚拟内存可用于 mmapped 文件。这可以暂时设置:
编辑文件:/etc/sysctl.conf
修改或加入 vm.max_map_count=655360
执行 sysctl -p 使之生效
文件句柄
通过修改系统的句柄限制,来让 elasticsearch 支持更多同时处理能力。
编辑文件:vi /etc/security/limits.conf
es soft nofile 100001
es hard nofile 100002
es soft memlock unlimited
es hard memlock unlimited
其中的 es 为上面创建的 elasticsearch 执行用户。
JVM 内存
修改承载 elasticsearch 的 JAVA 虚拟机内存。
vi config/jvm.options
建议最小填写为 2G,不够 swap 来凑(非高性能 SSD 建议就别开了),曾经尝试 512M 小鸡,经常会报内存不够无法处理,所以如果是小鸡不建议玩,或者一点点细水长流的慢慢写入?
虚拟机的话,建议物理内存 3G 以上,这里填写 2G,一定是小于物理机的内存的。
-Xms2g
-Xmx2g
elasticsearch 配置
修改配置文件:
vi config/elasticsearch.yml
打开基础常见选项:
# 节点名称
node.name: node-1
# 指定数据存储目录
path.data: /mnt/hd1/es/data
# 指定日志存储目录
path.logs: /mnt/hd1/es/logs
# 指定 IP 地址
network.host: 192.168.1.112
# 指定端口
http.port: 9200
# 指定主节点
cluster.initial_master_nodes: ["node-1"]
赋值权限
chown es:es /usr/local/elasticsearch
chown es:es /mnt/hd1/es
chmod -R 775 /usr/local/elasticsearch
chmod -R 775 /mnt/hd1/es
运行 ES
su - es -c '/usr/local/elasticsearch/bin/elasticsearch -d'
查看 ES 状态
# curl http://192.168.1.112:9200/_cat/nodes?pretty
192.168.1.112 56 97 63 2.25 4.18 7.11 cdhilmrstw * node-1
# curl http://192.168.1.112:9200/
{
"name" : "node-1",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "3oQSlikKS0qAn8dNXOcXtA",
"version" : {
"number" : "7.10.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "1c34507e66d7db1211f66f3513706fdf548736aa",
"build_date" : "2020-12-05T01:00:33.671820Z",
"build_snapshot" : false,
"lucene_version" : "8.7.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
安装 Kibana
照例,从官网下载并安装 kibana。
cd /usr/local
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.1-linux-x86_64.tar.gz
tar -xzf kibana-7.10.1-linux-x86_64.tar.gz
mv kibana-* kibana
cd kibana
配置文件
修改配置
vi config/kibana.yml
打开基础选项
# kibana 监听端口
server.port: 5601
# 监听的 host 地址
server.host: "192.168.1.112"
# 服务器名称
server.name: "kibana-server"
# 配置 ES 的地址
elasticsearch.hosts: ["http://192.168.1.112:9200"]
# kibana 日志记录文件
logging.dest: /var/log/kibana.log
赋值权限
给予 kibana 运行目录及日志文件权限。
chown -R es:es /usr/local/kibana
chmod -R 775 /usr/local/kibana
chmod 777 /var/log/kibana.log
运行 kibana
su - es -c '/usr/local/kibana/bin/kibana serve>/dev/null 2>&1 &'
稍等片刻你就可以通过浏览器打开 kibana 界面了。
http://192.168.1.112:5601/app/management/data/index_management/indices
创建索引
根据现数据文件,在 es 中创建我们需要的索引库。
创建 Q 绑索引
Q 绑文件我们可以通过 editor 打开,里面有两个字段,一个是 QQ 号码,一个是手机号。
PUT /qq
{
"mappings" : {
"properties" : {
"qq" : {
"type" : "keyword"
},
"phone" : {
"type" : "keyword"
}
}
},
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 0
}
}
}
创建微博索引
PUT /weibo
{
"mappings" : {
"properties" : {
"phone" : {
"type" : "keyword"
},
"uid" : {
"type" : "keyword"
}
}
},
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 0
}
}
}
创建 Facebook 索引
Facebook 的数据比较乱,由于也是多语言,整理起来也是很麻烦。这里只记录几个比较重要的基础数据:id、phone、性别、名字、email
PUT /facebook
{
"mappings" : {
"properties" : {
"phone" : {
"type" : "keyword"
},
"id" : {
"type" : "keyword"
},
"first_name" : {
"type" : "keyword"
},
"last_name" : {
"type" : "keyword"
},
"sex" : {
"type" : "keyword"
},
"from_area" : {
"type" : "keyword"
},
"current_area" : {
"type" : "keyword"
},
"work_area" : {
"type" : "keyword"
},
"email" : {
"type" : "keyword"
},
"country" : {
"type" : "keyword"
}
}
},
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 0
}
}
}
关闭索引刷新
在入库时,关闭索引刷新,可以让 es 写入速度更高。
PUT /weibo/_settings
{ "refresh_interval": "-1" }
PUT /qq/_settings
{ "refresh_interval": "-1" }
打开索引刷新
在数据写入完毕后,再打开索引刷新,这样就可以查询数据了。
PUT /weibo/_settings
{ "refresh_interval": "10s" }
PUT /qq/_settings
{ "refresh_interval": "10s" }
写入数据到 ES
这里你需要自己写一个程序将数据从文件读读入并写入到 es 中,不提供写入源码,只提供写入请求体参考:
QQ 入库:
{
"index": "qq",
"body": [
{
"index": {
"_index": "qq"
}
},
{
"qq": "12345",
"phone": "15222222222"
},
{
"index": {
"_index": "qq"
}
},
{
"qq": "10001",
"phone": "15522210101"
}
]
}
微博入库:
{
"index": "weibo",
"body": [
{
"index": {
"_index": "weibo"
}
},
{
"uid": "3057540037",
"phone": "18999999999"
},
{
"index": {
"_index": "weibo"
}
},
{
"uid": "5263746550",
"phone": "13000000000"
}
]
}
查询 QQ 绑定数据
根据 QQ 查询绑定手机号:
GET /qq/_search
{
"query": {
"match": {
"qq": "10001"
}
}
}
根据手机号查询所属 QQ 号:
GET /qq/_search
{
"query": {
"match": {
"phone": "13600000000"
}
}
}
查询微博绑定数据
根据微博 uid 查询绑定手机号:
GET /weibo/_search
{
"query": {
"match": {
"uid": "3057540037"
}
}
}
根据手机号查询微博 uid:
GET /weibo/_search
{
"query": {
"match": {
"phone": "13800002595"
}
}
}
删除文档
在写入数据的过程中可能会出错,即可能写入了错误的数据,你需要将这一部分数据删除,重新导入,那么可以通过下面的方法删除索引的文档数据。
POST /facebook/_delete_by_query
{
"query": {
"match": {
"country": "Egypt"
}
}
}
这个过程可能会超时报错,你可以通过相同的条件反复查询确认是否已经被删除。
比如这样:
POST /facebook/_count
{
"query": {
"match": {
"country": "Egypt"
}
}
}
就相关问题,网上还会有一些解决方案,比如增加一些参数来让他不超时或者忽略处理。
// ?wait_for_completion=false task 任务模式,不等待结果后台执行。
// ?conflicts=proceed 忽略,跳过冲突文档不更新
POST /facebook_a/_delete_by_query?wait_for_completion=false
{
"query": {
"match": {
"country": "Egypt"
}
}
}
POST /facebook_a/_delete_by_query?conflicts=proceed
{
"query": {
"match": {
"country": "Egypt"
}
}
}
如果你用了 task 任务模式删除,那么你可以通过下面的脚本查看任务运转状态:
GET /_tasks/3OPgrYDvTNak3zPfHus7ag:1302009
后面的是前文创建任务产生的任务 ID,拼接上去就行了,非常简单。
如果你发现文档一直没有被删除,那么你可能设置了前面的刷新时间,这个网上也没有找到答案,我实际测试中就遇到了。
那么你需要将对应的索引刷新时间恢复正常:
PUT /facebook/_settings
{ "refresh_interval": "5s" }
现在还有下载地址吗
博主可以分享一下下载地址吗。呜呜呜