Elasaticsearch Оптимизация 650 миллионов записей

Я пытаюсь выяснить, какое решение лучше всего подходит для elasticsearch, если мои записи будут масштабироваться до 658 миллионов записей в год. Фактически теперь у меня есть один индекс для всех моих записей с 2 ​​шардами и 0 репликами. Кроме того, я заметил, что с 356k записями и одним индексом сортировка и поиск работают быстрее, чем 365 индексов с 1000 записями. Вопрос в том, как лучше и быстрее хранить данные в эластичном формате для 658 миллионов записей, если я собираюсь выполнять поиск с сортировкой и удалять записи или индексы старше одного года?

Версия Elasticsearch 6.2, javascript api.

const defaultPageSize = 10
const indexTemplateSettings = {
    number_of_shards: 2,
    number_of_replicas : 0,
    max_result_window: 1000000000,
    'index.routing.allocation.enable': 'all',
}

const createClient = () =>
    new elasticsearch.Client({
        host: `${config.elastic.host}:${config.elastic.port}`,
        log: config.elastic.logLevel,
        httpAuth: `${config.elastic.userName}:${config.elastic.password}`,
    })

export const get = ({index, skip = 0, pageSize = defaultPageSize, search, sort = {by: 'timestamp', direction: 'desc'}}) => new Promise(async resolve => {
    try {
        logger.silly(`getting data from elastic: index: ${index}, skip: ${skip}, pageSize: ${pageSize}`)

        let client = createClient()

        const sortSettings = {
            order: `${sort.direction.toLowerCase()}`,
            missing: '_last',
            unmapped_type: 'long',
        }

        const params = {
            from: skip,
            size: pageSize || undefined,
            index: `${index.toLowerCase()}`,
            filter_path: 'hits.hits._source, hits.total',
            body: {
                query: {'match_all': {}},
                sort: {
                    [`${sort.by}.keyword`]: sortSettings,
                    [`${sort.by}.seconds`]: sortSettings,
                },
            },
        }

        if (search) {
            params.body.query = {
                query_string : {
                    query: `*${search}* OR *${search}`,
                    analyze_wildcard: true,
                },
            }
        }

        await client.search(params,
            (e, {hits: {hits:  data = [], total: totalCount} = {hits: [], total: 0}} = {}) => {
                logger.silly(`elastic searching completed. Result: contains ${totalCount} items`)

                resolve({items: data.map(t => t._source), totalCount})
            })
    } catch (e) {
        logger.error(e)
    }
})

export const push = (message, type) => new Promise(async resolve => {
    try {
        let client = createClient()
        let oneYearAgoTime = new Date(new Date().setFullYear(new Date().getFullYear() - 1)).toISOString().substring(0, 10)
        let indexCreationTime = new Date('2016-04-27').toISOString().substring(0, 10)

           await client.deleteByQuery({
            index: type.toLowerCase(),
            body: {
                query: {
                    range: {
                        '_timestampIndex' : {
                            lte: oneYearAgoTime,
                        },
                    },
                },
            },
        } , (error, response) => {
            logger.silly('Deleted of data completed', response)
        })

        await client.index({
            index: type.toLowerCase(),
            type,
            body: {
                ...message,
                _timestampIndex: indexCreationTime,
            },
        },
        (error, response) => {
            logger.silly('Pushing of data completed', response)

            resolve(response)
        })

    } catch (e) {
        logger.error(e)
    }
})

person Palaniichuk Dmytro    schedule 02.04.2018    source источник
comment
Можете ли вы поделиться выводом _cat / index вашего кластера? Размер индекса в ГБ важен для выбора правильного номера шарда. Кроме того, сколько узлов у вас есть в вашей среде?   -  person Dario Balinzo    schedule 02.04.2018
comment
1. зеленый открытый вызов N7CbN9RMTYuUxU3Hegoq9Q 2 0 1608588 0 332.9mb 332.9mb 2. теперь у меня один узел   -  person Palaniichuk Dmytro    schedule 02.04.2018


Ответы (1)


  1. 1000 документов на сегмент - это слишком мало. Как правило, осколок должен находиться в диапазоне ГБ; в зависимости от варианта использования от 10 ГБ (поиск) до 50 ГБ (журналы) - при условии, что у вас есть машина подходящего размера. Если я правильно понял в вашем комментарии, у вас 1,6 миллиона документов, которым требуется 333 МБ дискового пространства. Таким образом, у вас будет примерно в 400 раз больше документов, то есть около 133 ГБ данных; может 10 осколков? Если вы хотите правильно протестировать это, используйте 1 осколок и посмотрите, когда он взорвется - это должно дать вам представление о максимальном размере осколка.
  2. Удаление документов из указателя всегда будет дорогостоящим. Индексы на основе времени (если ваши шарды достаточно большие) или фильтры (возможно, даже отфильтрованный псевдоним в течение нужного периода времени) может позволить вам избежать частого удаления большого количества документов.
person xeraa    schedule 03.04.2018