百万商品数据写入 ES :33w/s

1,428 阅读15分钟

一、前言

本文主要围绕这三个主题展开:

百万商品写入压测-0.png

  • 前言:了解背景
  • Mock 数据:制造数据
  • 性能压测案例

先了解下商品数据模型:

字段名称类型
skuId商品Idkeyword
skuName商品名称text
category商品分类keyword
basePrice商品价格integer
vipPrice商品会员价格integer

商品核心索引如下:

商品的索引名:career_plan_sku_index_序号。 为了测试,使用不同的索引。

PUT /career_plan_sku_index
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":1
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

分片数量的设置的考虑:

  1. 节点数:3 个。
  2. 每个节点上有一个 shard 数据分片,每个 shard 数据分片可以有1个副本。

IK 分词器的分词类别:

  • ik_max_word 会尽可能把一个词拆分为多个分词组合

例如:北京人民大厦,拆分为:北京人、北京人民、人民大厦、人民、北京人民大厦。

  • ik_smart 智慧拆分

例如:北京人民大厦,拆分为:北京、人民、大厦

ES 写入优化

根据 官网文档 写入优化有:

  1. Use bulk requests:使用批量 bulk 上传。

  2. Use multiple workers/threads to send data to Elasticsearch:使用多线程。

  3. Unset or increase the refresh interval设置 refresh_interval 值,默认 1s。

    ES 的近实时搜索: 写入后 1s 就能搜索到。即默认每秒刷新一下。

    为了优化写入速度,可提高该值,从而减少频繁的 refreshlucene 段合并。

    配置项默认值优化
    index.refresh_interval1s30s(官方推荐),120s
  4. Disable replicas fo initial loads初始时将副本数改为 0,数据写入完成后再改回来。 (提升巨大),此配置可以 动态调整

    配置项默认值优化
    number_of_replicas10
  5. Disable swapping:关闭交换区。

  6. Give memory to the filesystem cachePageCache 足够的内存。 (写入数据和读取数据都需要)

  7. Use auto-generated ids:使用自动生成的 id

  8. Use faster hardware:云主机有限制,当前云盘是性能最低的 PL0 性能级别的 ESSD 云盘。

  9. Indexing buffer size索引缓冲大小 ,默认 10%,即 JVM 10GB、索引缓冲区 1GB。

    配置项默认值优化
    indices.memory.index_buffer_size10%30%
    indices.memory.min_index_buffer_size48MB128MB
    indices.memory.max_index_buffer_size无限制无限制

其他优化点:

  1. translog:来记录两次 flush(fsync) 之间所有的操作,当机器从故障中恢复或者重启,可以根据此还原

  • translog 是文件,存在于内存中,如果掉电一样会丢失。
    • 默认每隔 5s 刷一次到磁盘中 | 配置项 | 默认值 | 优化 | | ------------------------------------- | ------- | ------ | | index.translog.durability | request | async | | index.translog.sync_interval | 5s | 120s | | index.translog.flush_threshold_size | 512MB | 2048MB |



二、Mock 商品数据

目的:商品核心索引数据写入,需先造数据。

写一个 Web 服务,接收参数,mock 数据,将数据写入 ES

  • mock 商品数据:有 10万 商品数据,写在 TXT 文件中,根据这份数据随机生成 100万数据。
  • 定义接口:用于外部调用,方便测试。
# TXT中数据如下:
10001,房屋卫士自流平美缝剂瓷砖地砖专用双组份真瓷胶防水填缝剂镏金色,品质建材,398.00,上海,540785126782

统一输入接口参数:

  1. 批次(batchSize:默认执行 1000 次批量插入。
  2. 批量插入数(bulkSize:默认每次批量插入 1000 条商品数据。
  3. 线程数(threadCount:默认 30个 线程同时进行,不同函数不同实现。

Tips: 单线程和多线程,调用接口不同。

举个栗子:

POST http://47.99.242.194:8080/api/mockData/mockData1
{
    "indexName": "career_plan_sku_index_51",
    "batchSize": 1000,
    "batchTimes": 1000
}

响应内容:
{
    "success": true,
    "data": {
        "startTime": "2022-04-06 00:41:17",
        "endTime": "2022-04-06 00:41:55",
        "totalCount": 1000000,
        "elapsedSeconds": 37,
        "perSecond": 27027
    },
    "errorCode": null,
    "errorMessage": null
}

(1)单线程批量插入

步骤如下:

  1. TXT 加载商品数据 10万 条
  2. 批量写入 ES
  3. 记录统计信息
public JsonResult mockData(@RequestBody MockDataDTO request) {

    String indexName = request.getIndexName();
    int batchTimes = request.getBatchTimes();
    int batchSize = request.getBatchSize();

    // 1. 从txt文件里面加载10w条商品数据
    List<ProductDTO> skuList = loadSkusFromTxt(); // 详细代码:略。

    long startTime = System.currentTimeMillis();

    // 2. 执行 batchTimes 次,批量写入 ES
    for (int i = 0; i < batchTimes; i++) {
        BulkRequest bulkRequest = buildSkuBulkRequest(indexName, batchSize, skuList);
        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT); 
    }

    long endTime = System.currentTimeMillis();

    // 3. 记录统计信息
    int totalCount = batchSize * batchTimes;
    long elapsedSeconds = (endTime - startTime) / 1000;
    long perSecond = totalCount / elapsedSeconds;
    log.info("此次共导入[{}]条商品数据,耗时[{}]秒,平均每秒导入[{}]条数据", totalCount,
             elapsedSeconds, perSecond);

    return JsonResult.buildSuccess(result);
}

private BulkRequest buildSkuBulkRequest(String indexName, int batchSize, 
                                        List<Map<String, Object>> skuList) {
    BulkRequest bulkRequest = new BulkRequest(indexName);
    Random random = new Random();
    for (int j = 0; j < batchSize; j++) {
        int index = random.nextInt(100_000); // 从这 10 万商品数据随机选
        // 参数封装:略。
        IndexRequest indexRequest = new IndexRequest().source(XContentType.JSON,
                                                              list.toArray());
        bulkRequest.add(indexRequest);
    }
    return bulkRequest;
}

(2)多线程批量插入

需求:100W 数据,多线程(30个)批量导入

主要使用的技术:

  • CountDownLatch:倒们栓,所有线程完成才算完成。
  • Semaphore:信号量,控制同时进行的任务数。线程获取信号就执行,获取不到则阻塞。
  • 线程池:使用 synchronousQueue 队列
  • 线程:进行批量插入,每完成一次任务,countDownLatch.countDown();

流程图如下:

2022-02-1217-36-33.png

步骤:

  1. 加载数据(100k 条商品数据)
  2. 初始化 信号量Semaphore、倒们栓CountDownLatch、线程池 ThreadPool
  3. 循环批次
  4. 获取信号量,提交任务到线程池,线程批量插入数据到 ES
  5. 等待所有批次完成
public JsonResult mockData(@RequestBody MockDataDTO request) {
    String indexName = request.getIndexName();
    int batchTimes = request.getBatchTimes();
    int batchSize = request.getBatchSize();

    // 1. 从txt文件里面加载10w条商品数据
    List<ProductDTO> skuList = loadSkusFromTxt(); // 详细代码:略。

    // 倒们栓:需要执行多少批次,用来判断任务是否完成
    CountDownLatch countDownLatch = new CountDownLatch(batchTimes);
    // 信号量:线程数,控制有多少个线程执行任务
    Semaphore semaphore = new Semaphore(threadCount); 

    // 线程池:最大线程数要大点
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(threadCount, threadCount * 2, 60, TimeUnit.SECONDS, new SynchronousQueue<>());

    long startTime = System.currentTimeMillis();
    for (int i = 0; i < batchTimes; i++) {
        // 获取信号量,获取不到就在这阻塞
        semaphore.acquireUninterruptibly();

        threadPoolExecutor.submit(() -> {
            try {
                BulkRequest bulkRequest = buildSkuBulkRequest(indexName, 
                                                              batchSize, skuList);
                restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
                log.info("线程[{}]插入[{}]条商品数据", 
                         Thread.currentThread().getName(), batchSize);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();        // 释放信号量 +1
                countDownLatch.countDown(); // 倒们栓 -1
            }
        });
    }

    long endTime = System.currentTimeMillis();

    countDownLatch.await(); // 倒们栓,等待任务完成

    threadPoolExecutor.shutdown(); // 手动关闭线程

    int totalCount = batchSize * batchTimes;
    long elapsedSeconds = (endTime - startTime) / 1000;
    long perSecond = totalCount / elapsedSeconds;
    log.info("此次共导入[{}]条商品数据,耗时[{}]秒,平均每秒导入[{}]条数据", 
             totalCount, elapsedSeconds, perSecond);

    return JsonResult.buildSuccess(result);
}



三、性能压测

ES 集群规划: 3 个节点,ES 内存 -Xms8g -Xmx8g剩下内存要预留给 PageCache

集群名节点名称端口机器配置
esclusteresnode-19300 98008C16G
esclusteresnode-29300 98008C16G
esclusteresnode-39300 98008C16G
kibana90002C4G
es-service80804C8G

ES环境-1.png

对照组: 写入 100W 数据

对照组A对照组 BQPS
默认参数 + 单线程优化参数 + 单线程2.6W / 4.5W
默认参数 + 30 线程优化参数 + 30 线程5.8W / 25W
默认参数 + 60 线程优化参数 + 60 线程16W / 33W

(1)测试:100W数据 + 默认参数 + 单线程批量导入

  1. 创建索引
PUT /career_plan_sku_index_51
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":1
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

可以使用 Kibana 来创建:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "career_plan_sku_index_51"
}
  1. 接口请求
  • 操作索引:career_plan_sku_index_51 索引
  • 每次批量插入 1000 条商品
  • 一共执行 1000 次批量插入
POST http://47.99.242.194:8080/api/mockData/mockData1
{
    "indexName": "career_plan_sku_index_51",
    "batchSize": 1000,
    "batchTimes": 1000
}

响应内容:
{
    "success": true,
    "data": {
        "startTime": "2022-04-06 00:41:17",
        "endTime": "2022-04-06 00:41:55",
        "totalCount": 1000000,
        "elapsedSeconds": 37,
        "perSecond": 27027
    },
    "errorCode": null,
    "errorMessage": null
}
  1. 查看索引信息
# 查看索引下文档的个数
GET /_cat/count/career_plan_sku_index_51?v&h=count

count
1000000


# 查看索引下文档的个数,索引占用的磁盘空间等
GET /_cat/indices/career_plan_sku_index_51?v

health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   career_plan_sku_index_51 CTheAa0AQ9imZTx3dcJIgg   3   1     332857            0    323.6mb        147.8mb
  1. 机器监控

2022-04-0600-43-06.png

2022-04-0600-45-33.png

线程数导入数据量耗时QPSCPU使用率网络带宽使用率云盘带宽使用率
1100W38S263151.24%24.99 Mbit/s5.27 K Byte/s

2022-04-0600-50-16.png


(2)测试:100W数据 + 默认参数 + 30多线程批量导入

  1. 创建索引
PUT /career_plan_sku_index_52
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":1
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

可以使用 Kibana 来创建:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "career_plan_sku_index_52"
}
  1. 接口请求
  • 操作索引:career_plan_sku_index_52 索引
  • 每次批量插入 1000 条商品
  • 一共执行 1000 次批量插入
  • 线程 30 个
POST http://47.99.242.194:8080/api/mockData/mockData2
{
    "indexName": "career_plan_sku_index_52",
    "batchSize": 1000,
    "batchTimes": 1000,
    "threadCount": 30
}

响应内容:
{
    "success": true,
    "data": {
        "startTime": "2022-04-06 00:55:29",
        "endTime": "2022-04-06 00:55:36",
        "totalCount": 1000000,
        "elapsedSeconds": 6,
        "perSecond": 166666
    },
    "errorCode": null,
    "errorMessage": null
}
  1. 查看索引信息
# 查看索引下文档的个数
GET /_cat/count/career_plan_sku_index_52?v&h=count

count
1000000


# 查看索引下文档的个数,索引占用的磁盘空间等
GET /_cat/indices/career_plan_sku_index_51?v

health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   career_plan_sku_index_52 7KDkZCqBRyyuXbqQLbPIRw   3   1     333613            0    244.8mb        120.9mb
  1. 机器监控
线程数导入数据量耗时QPSCPU使用率网络带宽使用率云盘带宽使用率
1100W17S588234.46%29.27 Mbit/s10.2 K Byte/s

2022-04-0600-59-52.png

2022-04-0601-01-48.png


(3)测试:100W数据 + 默认参数 + 60多线程批量导入

  1. 创建索引
PUT /career_plan_sku_index_53
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":1
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

可以使用 Kibana 来创建:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "career_plan_sku_index_53"
}
  1. 接口请求
  • 操作索引:career_plan_sku_index_53 索引
  • 每次批量插入 1000 条商品
  • 一共执行 1000 次批量插入
  • 60 个线程
POST http://47.99.242.194:8080/api/mockData/mockData2
{
    "indexName": "career_plan_sku_index_53",
    "batchSize": 1000,
    "batchTimes": 1000,
    "threadCount": 60
}

响应内容:
{
    "success": true,
    "data": {
        "startTime": "2022-04-06 01:06:30",
        "endTime": "2022-04-06 01:06:36",
        "totalCount": 1000000,
        "elapsedSeconds": 5,
        "perSecond": 200000
    },
    "errorCode": null,
    "errorMessage": null
}
  1. 查看索引信息
# 查看索引下文档的个数
GET /_cat/count/career_plan_sku_index_53?v&h=count

count
1000000


# 查看索引下文档的个数,索引占用的磁盘空间等
GET /_cat/indices/career_plan_sku_index_53?v

health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   career_plan_sku_index_53 hLXhhv0TR6qJ1oggAdh2Kw   3   1          0            0    242.1mb          121mb
  1. 机器监控
线程数导入数据量耗时QPSCPU使用率网络带宽使用率云盘带宽使用率
1100W6S1666663.55%29.26 Mbit/s11.4 K Byte/s

2022-04-0601-08-51.png

2022-04-0601-11-17.png


(4)优化测试:100W数据 + 优化参数 + 单线程批量导入

修改 ES 的配置:

# 修改
vim /app/elasticsearch/elasticsearch-7.9.3/config/elasticsearch.yml

# 写入优化参数
indices.memory.index_buffer_size: 30%
indices.memory.min_index_buffer_size: 128m

重启 ES 集群的三个节点:

# 找到 ES 进程
ps -ef | grep elasticsearch

# kill 进程
kill 1899

# 清空日志
echo '' > /app/elasticsearch/log/escluster.log

# 启动
/app/elasticsearch/elasticsearch-7.9.3/bin/elasticsearch -d

# 看日志
tail -f /app/elasticsearch/log/escluster.log

在创建索引时,配置 index module 的配置:官方文档

  1. 创建索引
PUT /sku_index_1
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":0,
        "index.refresh_interval": "120s",
        "index.translog.durability": "async",
        "index.translog.sync_interval": "120s",
        "index.translog.flush_threshold_size": "2048mb"
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

可以使用 Kibana 来创建:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "career_plan_sku_index_51"
}
  1. 接口请求
  • 操作索引:sku_index_1 索引
  • 每次批量插入 1000 条商品
  • 一共执行 1000 次批量插入
POST http://47.99.221.206:8080/api/mockData/mockData1
{
    "indexName": "sku_index_1",
    "batchSize": 1000,
    "batchTimes": 1000
}

响应内容:

  1. 查看索引信息
# 查看索引下文档的个数
GET /_cat/count/sku_index_1?v&h=count

count
1000000


# 查看索引下文档的个数,索引占用的磁盘空间等
GET /_cat/indices/sku_index_1?v
health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   sku_index_1 7-uPmooRS1iZ8kUNvvnrEg   3   0    1000000            0    203.3mb        203.3mb

  1. 服务日志输出:
2022-04-09 17:29:48.860  INFO 1650 --- [nio-8080-exec-1] c.c.e.controller.MockDataController      : 此次共导入[1000000]条商品数据,耗时[22]秒,平均每秒导入[45454]条数据

此次共导入[1000000]条商品数据,耗时[22]秒,平均每秒导入[45454]条数据
  1. 机器监控
线程数导入数据量耗时QPSCPU使用率网络带宽使用率云盘带宽使用率
1100W22S45454条/s4.46%45.98 Mbit/s12.12 次/s

2022-04-0917-34-13.png

2022-04-0917-34-50.png


(5)优化测试:100W数据 + 优化参数 + 30多线程批量导入

  1. 创建索引
PUT /sku_index_2
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":0,
        "index.refresh_interval": "120s",
        "index.translog.durability": "async",
        "index.translog.sync_interval": "120s",
        "index.translog.flush_threshold_size": "2048mb"
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

可以使用 Kibana 来创建:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "sku_index_2"
}
  1. 接口请求
  • 操作索引:sku_index_2 索引
  • 每次批量插入 1000 条商品
  • 一共执行 1000 次批量插入
  • 线程 30 个
POST http://47.99.221.206:8080/api/mockData/mockData2
{
    "indexName": "sku_index_2",
    "batchSize": 1000,
    "batchTimes": 1000,
    "threadCount": 30
}

响应内容:
{
    "success": true,
    "data": {
        "startTime": "2022-04-09 17:59:05",
        "endTime": "2022-04-09 17:59:10",
        "totalCount": 1000000,
        "elapsedSeconds": 4,
        "perSecond": 250000
    },
    "errorCode": null,
    "errorMessage": null
}
  1. 查看索引信息
# 查看索引下文档的个数
GET /_cat/count/sku_index_2?v&h=count

count
1000000


# 查看索引下文档的个数,索引占用的磁盘空间等
GET /_cat/indices/sku_index_2?v

health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   sku_index_2 susX8xNBRXmwv7ceviDPPQ   3   0    1000000            0    192.4mb        192.4mb

  1. 服务日志:
2022-04-09 17:59:10.176  INFO 1650 --- [nio-8080-exec-3] c.c.e.controller.MockDataController      : 此次共导入[1000000]条商品数据,耗时[4]秒,平均每秒导入[250000]条数据

此次共导入[1000000]条商品数据,耗时[4]秒,平均每秒导入[250000]条数据
  1. 机器监控
线程数导入数据量耗时QPSCPU使用率网络带宽使用率云盘带宽使用率
1100W4S250000条/s4.63%45.99 Mbit/s12.12 次/s

2022-04-0918-04-17.png

2022-04-0918-04-35.png


(6)优化测试:100W数据 + 优化参数 + 60多线程批量导入

  1. 创建索引
PUT /sku_index_3
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":0,
        "index.refresh_interval": "120s",
        "index.translog.durability": "async",
        "index.translog.sync_interval": "120s",
        "index.translog.flush_threshold_size": "2048mb"
    },
    "mappings":{
        "properties":{
            "skuId":{
                "type":"keyword"
            },
            "skuName":{
                "type":"text",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_smart"
            },
            "category":{
                "type":"keyword"
            },
            "basePrice":{
                "type":"integer"
            },
            "vipPrice":{
                "type":"integer"
            },
            "saleCount":{
                "type":"integer"
            },
            "commentCount":{
                "type":"integer"
            },
            "skuImgUrl":{
                "type":"keyword",
                "index":false
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            },
            "updateTime":{
                "type":"date",
                "format":"yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

可以使用 Kibana 来创建:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "sku_index_3"
}
  1. 接口请求
  • 操作索引:sku_index_3 索引
  • 每次批量插入 1000 条商品
  • 一共执行 1000 次批量插入
  • 60 个线程
POST http://47.99.221.206:8080/api/mockData/mockData2
{
    "indexName": "sku_index_3",
    "batchSize": 1000,
    "batchTimes": 1000,
    "threadCount": 60
}

响应内容:
{
    "success": true,
    "data": {
        "startTime": "2022-04-09 18:07:40",
        "endTime": "2022-04-09 18:07:44",
        "totalCount": 1000000,
        "elapsedSeconds": 3,
        "perSecond": 333333
    },
    "errorCode": null,
    "errorMessage": null
}
  1. 查看索引信息
# 查看索引下文档的个数
GET /_cat/count/sku_index_3?v&h=count

count
1000000


# 查看索引下文档的个数,索引占用的磁盘空间等
GET /_cat/indices/sku_index_3?v
health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   sku_index_3 lKlx4KQ2T4OL3FKNcoTTPA   3   0    1000000            0    227.8mb        227.8mb

  1. 服务日志:
2022-04-09 18:07:44.522  INFO 1650 --- [nio-8080-exec-5] c.c.e.controller.MockDataController      : 此次共导入[1000000]条商品数据,耗时[3]秒,平均每秒导入[333333]条数据
此次共导入[1000000]条商品数据,耗时[3]秒,平均每秒导入[333333]条数据
  1. 机器监控
线程数导入数据量耗时QPSCPU使用率网络带宽使用率云盘带宽使用率
1100W3S333333条/s4.1%45.98 Mbit/s12.12 次/s

2022-04-0918-10-49.png

2022-04-0918-11-49.png