Мисля, че не се нуждаете само от добър избор на база данни, но и от известно преструктуриране на приложението. Предполагам, че използвате централизирана база данни на Oracle и всеки от вашите 4 сървъра пише в една и съща база данни. И също така предполагам, че правите балансиране на натоварването от страна на клиента, т.е. вашите клиенти произволно избират един от сървърите за приложения, към който да изпратят заявката.
И така, ето някои от моите мисли за това:
– Защо не разделите базата данни на n сегмента (n = 4 във вашия случай). И накарайте всеки сървър на приложения да гледа собствения си сегмент всеки път, когато дойде нова заявка. Идеята е, че искате да избегнете всякакъв вид спорове. Тук има най-лош сценарий. Какво става, ако се окажете в ситуация, в която всички заявки идват към един от сървърите на приложения и шардът на този сървър на приложения вече е пълен, докато има празни слотове в фрагментите на други слотове. Ако вашите клиенти произволно избират сървър за приложения, ще се оправите. Но все пак бихте искали да се погрижите за горния най-лош сценарий. Така че моето решение за това би било: Ако сървър на приложения осъзнае, че неговият шард е пълен, той произволно ще избере друг фрагмент на друг сървър на приложения и ще поиска този шард за празен слот. Така че забележете, че се озовавате в същата ситуация, в която два сървъра на приложения могат да четат/записват един и същи ред от таблица. Но шансовете това да се случи са намалени с порядъци и вашата архитектура е по-стабилна.
Но можем да направим повече, за да се погрижим за ситуацията, при която 2 сървъра на приложения може да четат/пишат в един и същ шард, защото единият шард на сървъра на приложения е пълен. Ето някои идеи: -- Проверете-след-действайте винаги е проблем във всеки вид система за споделяне на състояние. Така че, ако два сървъра на приложения търсят един и същ шард за празен слот, те ще се конкурират (състезателно състояние). Това, което ще направя в този случай, е да напиша заявката си по такъв начин, че ако текущата стойност е различна от стойността, която прочетох, тогава логиката на моя сървър на приложения ще извърши търсенето отново. Ако текущата стойност е същата като стойността, която прочетох, маркирайте слота като НЕПразен. Моля, обърнете внимание, че трябва да направите това като една и съща транзакция, за да бъде атомарна. Трябва да е нещо като Compare-And-Swap (CAS). Без значение каква база данни използвате SQL или NoSQL, ще трябва да напишете логика във вашето приложение, за да се справите със сценариите Check-Ten-Act в случай на състезателни условия
Също така мисля, че Oracle не е чудесен избор. Първо, скъпо е и второ, изглежда, че всичко, от което се нуждаете, е хранилище за ключ-стойност, така че според мен Oracle е прекален за това. Също така, ако имате една база данни на Oracle, вие имате една точка на отказ там.
Така че като цяло клъстерното (или шардирано) хранилище на ключови стойности е добър подход, който можете да предприемете. Според мен Couchbase не е лош избор. Използвал съм го за управление на широкомащабни сесии. В нашия случай използвахме Moxi за картографиране (за възли на дивана за нас). В нашия случай, ако възелът на couchbase се повреди, на Moxi отне известно време (~ 2-5 минути), за да разбере, че този възел се е повредил и да избере нова главна реплика на couchbase. Но ако вашето приложение е по-чувствително, можете да използвате Couchbase клъстер без Moxi и да запазите логиката на картографиране на заявка към couchbase възел във вашето приложение.
Но в текущия ви сценарий, какво се случва, ако вашата база данни на Oracle спре? Сигурен съм, че времето ви на престой е повече от 3-5 минути. Също така нашето време за преодоляване на срив беше 2-5 минути, защото имахме 90+ couchbase възли. Във вашия случай вероятно ще ви трябват само няколко (4-5) и възстановяването при срив ще бъде за секунди.
Друго нещо, което бих направил във вашия случай е, че бих искал приложението да резервира някои слотове предварително, така че моето четене и писане да стане бързо. Така че, когато приложение има резервирани слотове, тези възли ще бъдат маркирани като „резервирани“. Ако този сървър на приложения някога спре, всички негови запазени възли ще бъдат освободени. Или можете да напишете вашето запитване така
ако сесия == "резервирана" и app_server.health != "АКТИВНА", тогава възелът се счита за свободен.
Така че чрез просто записване на app_server.health = INACTIVE във вашата база данни вие автоматично освобождавате всички маркирани от него възли. Надявам се, че предадох идеята
Мащабирането на инфраструктурата за данни е интересен проблем и нещо, което обичам. Уведомете ме, ако имате въпроси и ще се радвам да помогна.
Основните ми предложения са:
– Не можете ли да предприемете подход, при който използвате GUID за всяка потребителска сесия, вместо да разпределяте предварително изчислен идентификатор на сесия (или стойност) за всеки потребител?
-- Помислете за шардинг. Шардингът не означава преминаване към клъстерен подход. Можете да разделите с в един възел, за да избегнете конфликт между таблиците на базата данни.
-- Оценете NOSQL за ваша употреба. Couchbase (Документен магазин) е добър вариант и съм го използвал за съхраняване на потребителски сесии в голям мащаб. Ако искате да изберете безплатни алтернативи с отворен код, Riak, Redis също са добри. Redis не би предложил вградено клъстериране. Но най-вероятно нямате нужда от него. Redis е супер мощен и ще има много много бързо четене и запис. Twitter използва Redis за съхраняване на туитове на всички потребители.
-- В крайна сметка трябва да управлявате условията на състезание във вашия код. Така че избягвайте условията на състезание, но бъдете готови да се справите с тях, когато се случат
-- Ако имате само една Oracle DB, вече имате единична точка на повреда и вашето време за преход при срив така или иначе ще бъде няколко минути (или часове). Така че не се страхувайте да се впуснете в клъстерирани магазини за ключ-стойност като Couchbase, Voldemort и т.н. За клъстер от 4-5 бележки вашият отказ ще бъде доста бърз (за секунди)
person
snegi
schedule
25.10.2013