Pamięć współdzielona pomiędzy servletem a beanami.

0

Witam,

Mam taki oto problem: w aplikacji (wszystko w jednym warze) znajdują się servlet oraz message driven beany. Servlet odbiea zapytanie parsuje je zapisuje do bazy i wstawia cos na kolejke. Z kolejki kontener zbiera wiadomosc tworzy MDB ktory na danych wykonuje jakies dzialania. Moj problem lezy w wydajnosci nie chcialbym aby servler zapisywal do bazy powiedzmy milion rekordów (to są akurat realne liczby) po czym MDB z bazy odczytywał milion. Mój pomysł wyglądałby tak że w servlet w jakiś sposób zostawiałby w pamięci RAM (a tej mam pod dostatkiem) olbrzymią tablice (i przy okazji zapisywął do bazy) po zakończeniu zapisu do bazy wrzucał by na kolejke wiadomosc, tworzony byłby MDB który zamiast robić milion selektów wziął by dane z pamieci z tablicy stworzonej przez servlet. Moje pytanie brzmi czy jest to mozliwe. Jeśli wszystko działało by na jednej instancji JBOSSA to czy MDB z kontenera bedzie mial dostep do miejsca gdzies w pamieci gdzie servlet zapisal dane i jak fizycznie widzielibyscie implementacje tego mechanizmu? Tzn czy moge miec statyczna tablice gdzies tam w pamieci gdzie servlet wrzuca MDB odbiera i wszystko jest ok czy takie cos nie jest mozliwe.

0

w pierwszej lini mialo byc: wszystko w jednym earze a nie w warze :)

0

Jesli bedzie wszystko na jednym serwerze (nie ma clusteringu) i jest to faktycznie jeden EAR to mozesz wykorzystac jakas klase ze staryczna tablica czy cokolwiek.
A takie pytanie, o ile dobrze zrozumialem to co robisz - jesli wszystko jest na 1 serwerze, to dlaczego nie mozesz do servlety wstrzyknac kolejki, w petli parsowac i tworzyc StringMessage / ByteMessage czy cokolwiek co tam chcesz (zawsze mozesz napisac swoj wlasny typ), i wysylac na kolejke msg z danymi o jednym rekordzie. Pozniej MDB odbiera wiadomosc i ma w jej obrebie wszystkie informacje. Nie ma ani jednego inserta do bazy, nie ma ani jednego selekta, nie ma (dosc nieeleganckich) statycznych tablic czy takich tam.

0

Takie wsadzenie danych na kolejke bez zapisu i zostawienia sladu niestety nie zapewni mi bezawaryjnosci. Calosc musi byc objeta transakcja, nie moze sie zdazyc ze ktos wyciagnie wtyczke a ja nie bede mial sladu po danych ktore do mnie przyszly. W przypadku gdy mam dane w pamieci i zarzucilem je do bazy po wznowieniu pracy aplikacji ponownie zostanie utworzony bean ktory moze rozpoznac ze nie ma nic w pamieci i odwola sie do bazy, w momencie gdy polegac bede tylko na pamieci ram takie wznowienie nie bedzie mozliwe. Poza tym kolejki jms'owe zapisuja dane w bazie, przeciez opieraja sie bazie danych (standardowo na hsqldb).

0

No wiec jesl chcesz miec taka bezawaryjnosc to statyczne tablice tez nie pomoga, chyba ze bedziesz zapisywal i w bazie i w pamieci.

Poza tym kolejki jms'owe zapisuja dane w bazie, przeciez opieraja sie bazie danych (standardowo na hsqldb).

O so chozi? Nie wiem gdzie zapisuja kolejki JBossowe swoje informacje, i niespecjalnie mnie powinno to interdowac. Nawet jesli zapisuja w HSQL to to jest zapisywanie w pamieci, jesli nie wierzysz to poczytaj o tej bazie.

0

No właśnie taki mam plan zeby zapisywac i tu i tu. Chce uniknąć potem tych selektów bo inne funkcjonalnosci ktore bedą kręciły raporty bedą pobierały dane z bazy a tych bedzie b. duzo. Jeśli chodzi o kolejki to te w moim przypadku tez musza dawac gwarantowaną dostawę lub jej ponowienie w przypadku jakiejkolwiek awarii a więc chciał nie chciał będą musiały zapisywać dane aby zagwarantować niezawodność. Generalnie dane=pieniądze więc nie mogą przepaść.

0

Jesli chcesz aby po wyciagnieciu wtyczki w trakcie procesowania danych przez servlet dane byly w bazie to pamietaj ze musisz te dane wkladac do bazy w innej transakcji niz dodajesz dane na kolejke - i kazdy rekord musialby byc dodawany w swojej wlasnej transakcji. W innym przypadku, jesli dodawanie na kolejke i dodawanie do bazy jest w tej samej transakcji, gdy w polowie ktos wyciagnie wtyczke, i msg nie zostana odebrane przez MDB, i danych nie bedzie w bazie.

0

Mnie to pachnie "premature optimization". A na użycie static w środowisku EJB to już mi się włosy na głowie jeżą. No cóż, jak ktoś lubi sobie robić problemy, nikt mu nie zabroni. ;)

Natomiast co do JMSa na SQLu w Jbossie to: ssie, a przynajmniej do wersji Jboss 4.2 to była tragedia, i to nie tylko pod względem wydajności, a pod względem stabilności. Podobno mieli go przepisać na nowo. Czy to zrobili, nie wiem, w międzyczasie przeszliśmy na Springa i mamy własną implementacje kolejek [1].

Co do wydajności bazy danych, jeśli musicie mieć kolejkę prawdziwie [2] backupowaną bazą danych, to i tak zarżniecie bazę COMMITAMI, a nie odczytami - próbujesz rozwiązywać przedwcześnie NIEWŁAŚCIWY problem. Ja bym się raczej zastanawiał (jeśli wydajność faktycznie będzie problemem) jak rozbić te wasze kolejki na kilka dysków, a w szczególności log transakcyjny bazy. W naiwnej implementacji na jakiejś bazce opensource przy jednym dysku nie przejdzie wam więcej niż ~120 komunikatów / sek. Macie Oracla?

[1] Jeżeli naprawdę chcesz mieć maksymalną wydajność, to pozostaje napisać to sobie samemudopasowane pod konkretną bazę i konkretne wymagania, o ile NAPRAWDĘ WIESZ, CO ROBISZ. Cała trudność polega na tym, że taka kolejka, oprócz tego co napisałeś o pamięci, musi działać współbieżnie i transakcyjnie. Naprawdę zadanie dla ludzi z dużym doświadczeniem.

[2] Sam fakt, że coś tam wrzucacie do bazy danych jeszcze nie oznacza, że ich szlag nie trafi jak ktoś wyciągnie wtyczkę tuż po wykonaniu COMMIT. Szczególnie, jeśli używacie domyślnego HSQLDB i dysków SATA. A może pomyliłem się, macie tam SCSI?

0

A więc sprzęt nie jest problemem. Na pewno bedzie scsi i na pewno bedzie i duuuzo ramu oraz na 100% oracle zoptymalizowany przez bazodanowcow. Co do kolejek to na nie same nie bedzie wrzucane duzo danych, kolejki beda wykorzystane jedynie do uzyskania asynchronicznosci wywolania operacji. Gdy ktos wyciagnie wtyczke przez commitem tez nie bedzie problemem, bo nie odpowiemy w servlecie kodem ukonczenia operacji a wiec nie bedziemy musieli miec sladu po przyslanych danych. Logi bazodanowe tak jak i indeksy czy sprawdzanie constraintow bedzie wylaczone. Uzywac bedziemy ojdbc oraclowego dla szybszej komunikacji. Tak więc jeszcze raz caly proces: zczytywanie np. 1,5 gb danych+parsowanie(blok po bloku danych odbieranych z http request)+zapis do bazy (batch insert dla sparsowanych danych)+wstawienie komunikatu ze dane sa gotowe do obrobki na kolejke+commit+odpowiedz do clienta ze oderbalismy zapisalismy i bedziemy przerabiac.
Problem polega na tym ze po wsadzeniu danych na kolejke (kuuupa insertów) nie chcialbym z pozycji mbeana ktory bedzie te dane przerabial wykonywac selectow bo beda jeszcze inne watki demony ktore beda tych selektow wykonywac duzo. Tak wiec zakladajac ze ramu mamy pod dostatkiem szukam rozwiazania przekazania danych w pamieci z servletu do mbeana. Na razi przychodzi mi tylko najprostsze: statyczna tablica (mapa tablic bo takich requestow do servletow bedzie max 100 dziennie ale kazdy po 1,5-3,0 gb danych ktore wymagaja szybkiej obrobki). Pytam wiec czy ktos sie spotkal z takimm problemem i ma jakies ciekawe propozycje.

0

A po ukonczeniu parsowania calego 1.5gb na kolejke bedzie wysylana jedna wiadomosc dla calego bloku, czy jedna wiadomosc na kazdy "rekord" z tego bloku wyciagniety?
Jesl 1 wiadomosc na 1 rekord - umiesc dane w wiadomosci. Jesli 1 wiadomosc na caly blok 1.5gb - mozesz umiescic wszystkie rekordy w tej 1 wiadomosci - zakladajac ze po drodze nie bedzie zadnego serializowania ani rmi z marshallingiem to bedzie tak samo dzialac jak ta nieszczesna tablica statyczna. Jak wspomnial Krolik i ja wczesniej tez statici to nie jest eleganckie rozwiazanie.

0

Nie nie. Sparsowane dane maja być zapisane do bazy (nie ma to zwiazku z kolejkami) oraz pozostawione w pamięci (ta statyczna tablica). Na kolejke wysyłany jest tylko komunikat że przyszedł request został zapisany do bazy i można się nim zająć (w miare dostepności zasobów). Teraz gdy kontener tworzy MBD ten pobiera dane z tej statycznej tablicy w pamięci (lub w przypadku awarii z bazy danych, bo tam są sparsowane dane i jest wiadomość na kolejce czyli nawet po naglym restarcie calosc wstanie)

0

No czyli zamiat tablicy statycznej mozesz uzyc Message ktory MDB odbiera i pobiera z Msg te dane?

0

No właśnie nie. Bo jak wcześniej wspomnialem kolejka musi być transakcyjna i musi zapewniać niezawodność czy sama korzysta z bazy (przy stworzeniu wiadomości idą inserty do bazy ze wszystkimi danymi, a przy odbiorze wiadomości idą selecty) tak więc to mija się z celem bo nie dośc że dwa razy wykonuje inserty dużej ilości danych to i tak wykonywane są selecty ktorych chce uniknąć.

0

Nie rozumiesz co mowie. Nie mowie o zadnych dodatkowych selektach. Masz opcje zrobic statyczna tablice, albo mozesz ta tablice dodac do ciala wiadomosci, i w MDB tablice z tej wiadomosci wyjac i na niej dzialac. Nie ma statica, i nie widze rowniez dodatkowych selektor.
Dla mnie koniec tematu, bez sensu dyskusja.

0

Hmmm. Albo ja albo ty nie znamy specyfikacji JMS. Jeśli wiadomość ma być GWARANTOWANA. Czyli musi zostac dostarczona z kolejki o obsłużona to jest zapisywana podczas jej wysyłania na kolejke do bazy (a nawet zawsze jest zapisywana). Czyli wysyłając wiadomośc w której contencie znajduje się jakiś obiekt o wielkości 1,5gb to ten obiekt pojdzie do bazy!! Po to w konfiguracji np. na jbossie konfiguruje sie obiekt PostOffice który jest odpowiedzialny za zapisy do bazy. Tak więc jeszcze raz: dodanie wiadomości na kolejke==zapis wiadomości do bazy a poniewarz wiadomośc zawiera w sobie 1,5gb danych to one tez zostaną zapisane (moze jakiś clob, nie wiem) ale zapisane zostaną. Tak wię chciał nie chciał będzie znów insert, a przy odbiorze wiadomości będzie select tego wszystkiego. Tak mówi specyfikacja JMS.

0

Tak jest i już. Jeśli coś ma być gwarantowane to musi zostać zapisane do bazy. Co więcej MDB obierając wiadomość równierz musi założyć na jej odebrane transakcje bo w przypadku gdy nie powiedzie się coś podczas jego działania wiadomośc musi wrócić na kolejke (rollback ze strony MDB, oczywiście zarządzany przez kontener). Jak ty widziałbyś takie podstawowe mechanizmy bez zapisu do bazy??

0

Czlowieku, ja nie mowie ze nie masz zapisywac nic do bazy, tylko ze zamiast dodatkowej statycznej tablicy masz wlozyc dane do msg. Czytaj ze zrozumieniem, bedzie Ci latwiej. Nie wiem jak JBoss gwarantuje dostarczenie wiadomosci, nie uzywam go i nie bede uzywal.
Jesli cos ma byc gwarantowane to wcale nie oznacza ze jak napisales musi byc zapisane do bazy danych. Sa inne mozliwosci.
To ze kolejka na JBossie zapisuje cos do bazy (ja mowiles wczesniej dzieje sie w JBoss + Hsql) to wcale nie znaczy ze inne serwery aplikacji tak robia. Poza tym, Hsql siedzi w pamieci, sprawdzales ile sie wykonuja selecty i inserty? Poza tym jest to zdaje sie inna baza danych niz ta w ktora beda lupaly inne zapytania do raportow (jak napisales Oracle) wiec zupelnie nie czaje o czym piszesz. Chyba Krolik ma racje ze to jest premature optimization z Twojej strony.

Specyfikacja JMS nie mowi nic o bazach danych i zapisie do nich, najdalej w kierunku baz danych idzie przy opisie skladni selectorow wiadomosci (podzbior wyrazenia where z SQL) i tyle. Wiec chyba jednak Ty nie znasz specyfikacji.

No wiec napisz statyczna tablice, tylko nie zdziw sie jak przyjedize pora na clustering albo rozdzielenie kontenera servletow od kontenera ejb czy jms na innym serwerze i nagle przestanie to dzialac.

0

Jeśli kolejka ma byc transakcyjna to JEST zapis do bazy i jakiegokolwiek bys nie uzywal serwera to ten zapis jest. Ja się zgadzam że taki zapis nie jest konieczny i ze hsqldb operuje w pamieci. Ale hsqldb nie jest transakcyjny wiec nie ma tu zadnej gwarancji ani transakcji wiec u mnie z zalozenia bylo oracle(może źle wyjechalem tutaj ze specyfikacja JMS, chodziło mi raczej o obsługę transakcji w kolejkach opisaną w JEE). A ja potrzebuje tej gwarancji. Nie musisz sie napinać tylko słuchaj :) Ja rozumiem że pisałeś nietransakcyjne rozwiazania i na pewno to działało super jednak ja nie moge sobie na to pozwolić.

0

Co do rozdzialu kontenerów to na pewno nie nastąpi bo nie widzimy takie potrzeby zeby rząglować tak duża ilością danych pomiędzy serwerami. Poza tym ja wcale nie mowie że chce statyczną tablicę, ba ja bym chciał jej uniknąć ale uniknąć chce też selektów robionych przez MDB (przypominam ze odbior TRANSAKCYJNEJ wiadomości, niezależnie od serwera aplikacyjnego, wykonuje select) i pytalem o pomysly.

0

Ponownie napisze - nie wiem skad wiesz ze wszystkie implementacje JMS zapisuja cos do bazy, ja kawalek czasu z tym pracuje i gwarantuje Ci ze nie wszystkie implementacje tak robia.
Hsql nie jest transakcyjny? Co to znaczy, ze nie obsluguje transakcji? O czym Ty piszesz? Obsluguje (co prawda tylo read_uncommited ale obsluguje). Obsluguje rowniez transakcje rozproszone (http://hsqldb.org/doc/src/org/hsqldb/jdbc/jdbcDataSource.html i wyszukaj slowka "distributed").
Gdzie w specyfikacji JMS czy Javy EE masz cokolwiek o tym ze cos jest zapisywane do bazy?
Na jakiej podstawie wywnioskowales ze pisalem tylko rozwiazania nietransakcyjne?
Sie uparles na te selecty w transakcyjnych wiadomosciach...
Co do rozdzielenia kontenerow to nigdy nie wiesz czy nie bedzie nagle potrzebne.
Glupia dyskusja, nie rozumiemy sie a ty jeszcze jakies herezje opowiadasz. Pozdro.

1 użytkowników online, w tym zalogowanych: 0, gości: 1