Ubuntu32G服务器测试es数据库性能

一、环境准备

1、服务器系统信息

32G 4T x86服务器

2、es信息

版本:6.8.23

集群信息:单节点

索引:

{
    "example": {
        "mappings": {
            "docs": {
                "properties": {
                    "f1": {
                        "type": "text"
                    },
                    "f10": {
                        "type": "text"
                    },
                    "f11": {
                        "type": "text"
                    },
                    "f12": {
                        "type": "text"
                    },
                    "f13": {
                        "type": "text"
                    },
                    "f14": {
                        "type": "text"
                    },
                    "f15": {
                        "type": "text"
                    },
                    "f2": {
                        "type": "text"
                    },
                    "f3": {
                        "type": "text"
                    },
                    "f4": {
                        "type": "text"
                    },
                    "f5": {
                        "type": "text"
                    },
                    "f6": {
                        "type": "text"
                    },
                    "f7": {
                        "type": "text"
                    },
                    "f8": {
                        "type": "text"
                    },
                    "f9": {
                        "type": "text"
                    }
                }
            }
        }
    }
}

3、流量发送主机信息

 

二、实验步骤

1、搭建上述环境

2、日志发送脚本

public class EsTest {
    private static final String USERNAME = "es";
    private static final String PASSWORD = "password";
    private static final String INDEX_NAME = "example";
    private static final String URL = "http://IP:9200/example/docs/_bulk";
    public static void main(String[] args) {
        try {
            startUp();
        } catch (Exception e) {
            System.err.println("Exception caught in main method");
            e.printStackTrace();
        }
    }

    public static void startUp() throws Exception {
        try {
            // 创建连接池管理器
            PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
            // 设置最大连接数
            connManager.setMaxTotal(800);
            // 设置每个路由的最大连接数
            connManager.setDefaultMaxPerRoute(100);
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(100);
            executor.setMaxPoolSize(800);
            executor.setQueueCapacity(0);
            executor.setKeepAliveSeconds(1);
            executor.setThreadNamePrefix("ES-Task-Thread-");
            executor.initialize();

            // 批量大小
            final int batchSize = 100;

            for (int i = 0; i < 30; i++) {
                executor.execute(() -> {
                    System.out.println("Thread-" + Thread.currentThread().getName() + " is running");
                    try {
                        doPost(URL,connManager);
                    } catch (Exception e) {
                        System.err.println("Exception caught in thread: " + Thread.currentThread().getName());
                        e.printStackTrace();
                    }
                });
                Thread.sleep(1500);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("restarting...");
            startUp();
        }
    }

    public static String generateBatchData(int batchSize) throws JSONException {
        StringBuilder bulkData = new StringBuilder();
        for (int i = 0; i < batchSize; i++) {
            JSONObject jsonObject = generateRandomJsonObject();
            // 操作行
            bulkData.append("{ \"index\" : { \"_index\" : \"example\" } }\n");
            // 文档行
            bulkData.append(jsonObject.toString()).append("\n");
        }
        // 最后一个换行符
        bulkData.append("\n");
        return bulkData.toString();
    }

    public static JSONObject generateRandomJsonObject() throws JSONException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("f1",generateRandomEnglish(13));
        jsonObject.put("f2",generateRandomEnglish(13));
        jsonObject.put("f3",generateRandomEnglish(13));
        jsonObject.put("f4",generateRandomEnglish(13));
        jsonObject.put("f5",generateRandomEnglish(13));
        jsonObject.put("f6",generateRandomEnglish(13));
        jsonObject.put("f7",generateRandomEnglish(13));
        jsonObject.put("f8",generateRandomEnglish(13));
        jsonObject.put("f9",generateRandomEnglish(13));
        jsonObject.put("f10",generateRandomEnglish(13));
        jsonObject.put("f11",generateRandomEnglish(13));
        jsonObject.put("f12",generateRandomEnglish(13));
        jsonObject.put("f13",generateRandomEnglish(13));
        jsonObject.put("f14",generateRandomEnglish(13));
        jsonObject.put("f15",generateRandomEnglish(13));
        return jsonObject;
    }
    public static String generateRandomChinese() {
        int length = ThreadLocalRandom.current().nextInt(5, 11);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            // 中文字符的 Unicode 范围从 0x4E00 到 0x9FA5
            int val = 0x4E00 + ThreadLocalRandom.current().nextInt(0x9FA5 - 0x4E00 + 1);
            sb.append((char) val);
        }
        return sb.toString();
    }

    public static String generateRandomEnglish(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            // 生成随机的大写字母或小写字母
            boolean isUpperCase = ThreadLocalRandom.current().nextBoolean();
            int val;
            if (isUpperCase) {
                // 大写字母的 ASCII 范围从 65 到 90
                val = 65 + ThreadLocalRandom.current().nextInt(26);
            } else {
                // 小写字母的 ASCII 范围从 97 到 122
                val = 97 + ThreadLocalRandom.current().nextInt(26);
            }
            sb.append((char) val);
        }
        return sb.toString();
    }

    public static void doPost(String url, PoolingHttpClientConnectionManager connManager) {
        CloseableHttpClient httpClient = null;
        try {
            httpClient = HttpClients.custom()
                    .setConnectionManager(connManager)
                    .build();
            while (true) {
                try {
                    HttpPost httpPost = new HttpPost(url);
                    httpPost.addHeader("Content-Type", "application/json");
                    httpPost.addHeader("Authorization", getBasicAuthHeader(USERNAME, PASSWORD));
                    httpPost.setEntity(new StringEntity(generateBatchData(1000), StandardCharsets.UTF_8));
                    try (CloseableHttpResponse response = httpClient.execute(httpPost)) {

                        HttpEntity entity = response.getEntity();
                        if (entity != null) {
                            String responseContent = EntityUtils.toString(entity, "UTF-8");
                            // 可以在这里打印响应内容或其他操作

                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    // 如果发生异常,关闭当前的 httpClient 并重新创建
                    closeQuietly(httpClient);
                    httpClient = HttpClients.custom()
                            .setConnectionManager(connManager)
                            .build();
                } finally {
                    Thread.sleep(1000);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeQuietly(httpClient);
        }
    }

    private static void closeQuietly(CloseableHttpClient httpClient) {
        if (httpClient != null) {
            try {
                httpClient.close();
            } catch (IOException ignored) {
                // 忽略关闭时出现的异常
            }
        }
    }

    private static String getBasicAuthHeader(String username, String password) {
        String authString = username + ":" + password;
        byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes(StandardCharsets.UTF_8));
        return "Basic " + new String(authEncBytes);
    }
}

3、给es分配1G内存打流

4、给es分配16G内存打流 

三、实验结果

当es为1G时,不批量存储,直接插入数据,可以开400线程打,1秒入库大约2000-4000,一段时间后http连接崩溃

当es为1G时,批量存储,20线程一秒入库20000,索引健康度为red,一段时间后服务崩溃

es为16G时,批量存储,20线程,一秒入库20000,索引健康度为yellow,可以良好运行

40线程,一秒入库40000,http连接池崩溃

四、实验结论

ddos攻击或者大数据告警时,防护方要注意入库时不要让服务器崩溃,攻击者则可以想办法大量批量插入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值