博文記錄
教程分享 2020-12-12 20:39:03 1240 3

写在前面

近日网上各论坛,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" } 

 

Bin

2021-04-18 15:31

博主可以分享一下下载地址吗。呜呜呜

Bin

2021-04-18 15:38

@Bin 原来都可以下载的,我找到了

哈哈哈

2021-05-08 01:06

现在还有下载地址吗

發表評論
StudioEIM - 冒险者讲习所
0:00