Кэш объектов JSON с истечением срока действия для ответов GraphQL - PullRequest
1 голос
/ 15 мая 2019

Я создал кеш (nosql), который принимает графические объекты json и выравнивает их. Это означает, что все дочерние объекты заменяются ссылками и хранятся отдельно. Например, с учетом приведенного ниже ввода:

{
    "users": [
         {"type": "user", "id": 1, "name": "bob"}, {"type": "user", "id": 1, "name": "bill"}
    ]
}

Хранится как:

{ 
    "users": ["ref-user-1", "ref-user-2"],
    "ref-user-1": {"type": "user", "id": 1, "name": "bob"},
    "ref-user-2": {"type": "user", "id": 1, "name": "bill"}
}

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

Проблемы связаны с недействительностью кэша. Как мы узнаем, актуальна ли запись в кэше? Ради этого поста мы можем сказать, что объект действителен, если все его поля были кэшированы в течение 2 часов. Если другой запрос приходит с user-1, мы хотели бы обновить наши локальные временные метки для полей, возвращаемых этим запросом.

Как сохранить метки времени для каждого поля в рабочем порядке?

Рассмотренные варианты:

  1. Каждое значение получает свою собственную метку времени. Все поиски были бы O (1), но у нас была бы тонна дублированных данных временной метки.

    "ref-user-1": {"type": "user", "id": {"val": 1, "ts": "1557941674"}, "name": {"val": "bob" "ts": "1557941674"}}

  2. Хранение временных меток свойств как наборов свойств с одной временной меткой на набор. Поиск будет медленным, но это уменьшит данные. Обновления также могут быть довольно медленными. Было бы хорошо, если бы мы могли превратить поля в хеш, и проверить, содержал ли больший хеш все поля в меньшем хэше.

    "ref-user-1": {"type": "user", "id": 1, "name": "bob", "field_sets": ["ts": "1557941674", "fields": ["id", "name"]] }

  3. Причудливая структура данных, которую я не рассматривал ...

1 Ответ

1 голос
/ 15 мая 2019

Как говорится в старой шутке: «В компьютерной науке есть только две серьезные проблемы. Именование, аннулирование кэша и отключение одной ошибкой».

Так что это сложная проблема, и она должна быть трудной.

Я хотел бы предположить, что важно не то, как недавно были возвращены данные, а то, как недавно данные были кэшированы.В противном случае часто запрашиваемая часть данных может устареть и оставаться в ней бесконечно долго.(Смотри, я сказал, что аннулирование кэша сложно!)

Это говорит о том, что временные метки должны основываться на том, когда кэш был недавно обновлен.Таким образом, вы можете просто вернуть данные, если они менее 1,5 часов.Если ему 1,5-2 часа, вы подбрасываете монету.(с возрастающей вероятностью перевернуть его).Если вы старше, вы рассматриваете это как недействительное.Эта стратегия делает вероятным, что данные обновляются только один раз, даже если к ним осуществляется очень активный доступ.

При таком подходе требуется отметка времени для каждого свойства.И позволяет заданию, которое знает, что оно изменило некоторые из этих данных, превентивно лишает законной силы некоторые поля.Когда вы идете, чтобы заполнить объект, вы знаете, что это произошло, потому что есть ссылка на данные, которых там нет, и вы знаете, что вам нужно обновить их.(Независимо от того, выполняется ли обновление на уровне кэширования или на уровне приложений, это решение по проекту может быть принято в любом случае.)

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