Поиск через черепки?

1112 Да, вы правы. Компилятор может делать то, что он хочет, при условии, что наблюдаемое поведение является тем же, что и абстрактная машина, которую может создать . Но это не драматично само по себе: почему мы заботимся о том, чего нельзя наблюдать? В этом смысл оптимизации компиляторов.

Пример:

int main() {
    int a;
    for (int i=INT_MAX; i>=0; i--) {
        a = i;
    }
    printf("%d\n", a);
    return 0;
}

Единственное наблюдаемое поведение это то, что он будет печатать 0 за один раз. Таким образом, компилятор может оптимизировать цикл таким образом:

int main() {
    printf("%d\n", 0);
    return 0;
}

Что это означает по сути, что вы не можете использовать пустые циклы для добавления задержек, потому что они могут быть оптимизированы не производит задержки вообще.

ИМХО, самый драматичный побочный эффект, если компилятору разрешено предполагать, что в программе не может быть неопределенного поведения.

Второй пример:

int main() {
    struct {
        int a[16];
        int b[16];
    } s;

    for (i=0; i<16; i++) {
        s.a[i] = i;
        s.b[i] = 2 * i;
    }
    for (i=0; i<32; i++) {
        printf(" %d", s.a[i]);      // UB array access past upper bound
    }
    printf("\n");
    return 0;
}

Наивный компилятор должен отображать все числа от 0 до 31, потому что мы знаем, что массивы s.a и s.b должны быть смежными, а арифметика указателей должна давать &(s.b[0]) == &(s.a[16]) , Но оптимизирующий компилятор может заметить, что значения s.b никогда не используются в наблюдаемом поведении, если не задействован ни один UB, и он свободен для оптимизации доступа к массиву s.b и даже для оптимизации члена b. Здесь следует ожидать аварийных или случайных значений ... Хуже того, действительно умный компилятор может заметить, что в цикле печати есть прошлые связанные обращения. С этого момента поведение программы не определено, и компилятор может, например, остановить цикл после печати 16-го значения. Нет ошибок, но напечатано только 16 значений ...

8
задан Gintautas Miliauskas 13 October 2010 в 21:04
поделиться

4 ответа

Нет никакого чудодейственного средства.

Поиск каждого черепка по очереди вне рассмотрения, очевидно, из-за невероятно высокой задержки, которой Вы подвергнетесь.

Таким образом, Вы хотите искать параллельно, если Вы имеете к.

Существует две реалистических опции, и Вы уже перечислили их - индексация и параллелизировали поиск. Позвольте мне вдаваться в немного большее количество подробностей о том, как Вы пошли бы о разработке их.

Ключевое понимание, которое можно использовать, - то, что в поиске, Вам редко нужен полный набор результатов. Вам только нужно первое (или энный) страница результатов. Таким образом, существует довольно мало пространства для маневра, можно использовать для уменьшения времени отклика.

Индексация

Если Вы знаете атрибуты, на которых будут искаться пользователи, можно создать пользовательские, отдельные индексы для них. Можно создать собственный инвертированный индекс, который укажет на (черепок, recordId) кортеж для каждого критерия поиска, или можно сохранить его в базе данных. Обновите его лениво, и асинхронно. Я не знаю Ваши требования к приложению, могло бы даже быть возможно просто восстановить индекс каждую ночь (значение, что у Вас не будет новых записей ни в какой данный день - но это могло бы быть хорошо для Вас). Удостоверьтесь, что оптимизировали этот индекс для размера, таким образом, он может уместиться в памяти; обратите внимание, что Вы можете черепок этот индекс, если Вы должны.

Естественно, если люди могут искать что-то как "lastname='Smith' OR lastname='Jones'", можно считать индекс для Smith, считать индекс для Jones и вычислить объединение - Вы не должны хранить все возможные запросы, просто их части здания.

Параллельный поиск

Для каждого запроса отошлите запросы к каждому черепку, если Вы не знаете, какой черепок искать, потому что поиск, оказывается, находится на ключе распределения. Выполните асинхронные запросы. Ответьте пользователю, как только Вы получаете первую ценность страницы результатов; соберите остальных и кэш локально, так, чтобы, если пользователь совершает нападки "затем", Вы имели результаты готовыми и не должны были повторно запрашивать серверы. Таким образом, если некоторые серверы занимают больше времени, чем другие, Вы не должны ожидать на них для обслуживания запроса.

В то время как Вы в нем, регистрируете время отклика серверов черепка для наблюдения потенциальных проблем с неровными данными и/или распределением нагрузки.

7
ответ дан 5 December 2019 в 15:28
поделиться

Я предполагаю, что Вы говорите о черепках а-ля: http://highscalability.com/unorthodox-approach-database-design-coming-shard

Если Вы читаете ту статью, он вдается в некоторые подробности о точно Вашем вопросе, но длинный короткий ответ, Вы пишете код пользовательского приложения для объединения разрозненных черепков. Можно сделать некоторое умное хеширование, чтобы и запросить отдельные черепки и вставить данные в черепки. Необходимо задать более конкретный вопрос для получения более определенного ответа.

2
ответ дан 5 December 2019 в 15:28
поделиться

Вам на самом деле нужен каждый поиск для удара каждого черепка, или по крайней мере каждый поиск должен быть выполнен против индекса, который содержит данные из всех черепков, которые сводятся к тому же самому.

По-видимому, Вы черепок на основе единственного свойства пользователя, вероятно, хеш имени пользователя. Если Ваша функция поиска позволяет пользователю искать на основе других свойств пользователя, ясно, что нет никакого единственного черепка или подмножества черепков, которые могут удовлетворить запрос, потому что любой черепок мог содержать пользователей, которые соответствуют запросу. Вы не можете исключить черепки прежде, чем выполнить поиск, который подразумевает, что необходимо выполнить запрос против всех черепков.

1
ответ дан 5 December 2019 в 15:28
поделиться

Можно хотеть посмотреть на Сфинкса (http://www.sphinxsearch.com/articles.html). Это поддерживает распределенный поиск. GigaSpaces имеет поддержка слияния и параллельный запрос. Это может также быть сделано с MySQL Proxy (http://jan.kneschke.de/2008/6/2/mysql-proxy-merging-resultsets).

Создавать non-sharded индексировало виды поражений цель черепка во-первых :-) Централизованный индекс, вероятно, не будет работать, если черепки были необходимы.

Я думаю, что все черепки должны быть поражены параллельно. Результаты должны быть фильтрованы, оценены, отсортированы, сгруппированы и результаты, объединенные от всех черепков. Если сами черепки становятся разбитыми, необходимо сделать обычное (reshard, увеличиться, и т.д.) не приводить в восторг их снова.

1
ответ дан 5 December 2019 в 15:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: