TCP/IP czy webservice (R)

0

Może głupie pytanie, ale nie jestem specjalistą, a mam zadanie do wykonania. Mam do wystawienia trochę kodu produkcyjnego w R pisanego przez osobny zespół. Po prostu zestaw funkcji, dość liczny. Gdybyście mieli zaprojektować coś takiego, to użylibyście bardziej binarnych gniazd TCP/IP, gdzie podawalibyście nazwy funkcji i parametry, czy jednak RESTowe API wystawione po HTTP? Mogę tak i tak, użyć albo gniazd TCP albo OpenCPU. System będzie odpytywany dość intensywnie, więc powinno to być skalowane, czyli wychodzi mi że OpenCPU na Apache2 w trybie MPM-prefork i włączonym cache. Z drugiej strony binarnie idzie mniej danych po sieci. W końcu JSON to czysty tekst. Ale w dzisiejszych czasach chyba już tylko się pisze webservice'y? Wszystko chodzi po wewnętrznej sieci, ale wolałbym żeby ilość danych nie szła w kosmos, ale żeby dało się taki serwis odpytać w miarę łatwo np. curlem albo z C#. Albo inaczej, czy ktoś jeszcze używa binarnych protokołów po sieci?

0

HTTP2 + msgpack czy inny binarny format i masz zdecydowaną redukcję pakietów, a do tego możesz użyć istniejących narzędzi do loadbalancingu. Win Win.

0

Użycie binarnego protokołu oznacza że będzie to mega bolesne jeśli ktoś inny z inną technologią będzie chciał z tego korzystać.

0
Shalom napisał(a):

Użycie binarnego protokołu oznacza że będzie to mega bolesne jeśli ktoś inny z inną technologią będzie chciał z tego korzystać.

Ale tu nie było nic mowy o tym, że dokumentacji nie będzie...

0

Dokumentacja nie ma nic do rzeczy. Nawet jeśli uzyjesz jakiejś biblioteki do (de)serializacji tych binarnych zapytań to może ona nie mieć bindingów dla technologii XYZ. A jeśli protokół będzie twój to znów ktoś spędzi sporo czasu klepiąc sobie warstwę komunikacji. Z podobnych powodów Webservices wyparły praktycznie całkowicie rozwiązania w stylu CORBA już dawno temu, mimo że te drugie niby oferowały szybsze działanie (mocna kompresja danych) i więcej możliwości (asynchroniczność np.) i miały gotowe bindingi do wielu technologii.

0
Shalom napisał(a):

Dokumentacja nie ma nic do rzeczy. Nawet jeśli uzyjesz jakiejś biblioteki do (de)serializacji tych binarnych zapytań to może ona nie mieć bindingów dla technologii XYZ. A jeśli protokół będzie twój to znów ktoś spędzi sporo czasu klepiąc sobie warstwę komunikacji. Z podobnych powodów Webservices wyparły praktycznie całkowicie rozwiązania w stylu CORBA już dawno temu, mimo że te drugie niby oferowały szybsze działanie (mocna kompresja danych) i więcej możliwości (asynchroniczność np.) i miały gotowe bindingi do wielu technologii.

W sumie, tak na to nie patrzyłem, zawsze myślałem, że jak trzeba coś wyklepać to się klepie.
A ty tu lenia poziom mastera masz, jak się nie chce robić, to wszystko jest złe.

1

Każdy "własny kod" kosztuje sporo. Nie dość że trzeba go napisać to jeszcze potem utrzymywać. A jak wymyślasz jakieś swoje własne "standardy" to już w ogóle masakra. Jak skończysz gimnazjum i pójdziesz do pracy to zobaczysz, że stosowanie powszechnie przyjętych rozwiązań w 99% przypadków jest lepszym wyjściem.

0

Macie racje, a zatem to było głupie pytanie, ale zawsze to lepiej usłyszeć fachowców. Decyzja podjęta, REST API i OpenCPU. Co do binarki to macie rację z CORBA, jeden ze starszych wiekiem kolegów, pracujący przy utrzymaniu dość wiekowych kodów opartych o ten standard zapronował właśnie takie rozwiązanie. Dokumentacja jest dość skromna. Przydałby się plik DISCO, żeby webservice się przedstawił, ale OpenCPU potrafi wymienić wszystkie funkcje danego pakietu, więc też się nada. Dzięki za wasze opinie.

0

Ja bym jednak zaproponował ProtoBuf od Google. Wsparcie języków dość dobre, a zdecydowanie lepiej przemyślane niż Corba. Ewentualnie Cap'n'proto, ale tu wsparcie jest już słabsze.

0

Ja bym zadał sobie najpierw pytania pomocnicze.

  1. Czy ta funkcjonalność wołania funkcji w R jest bezpieczna z perspektywy używania przez wielu klientów "jednocześnie"? Czy może trzeba zapewnić jakiś mechanizm synchronizacji?
  2. Czy klienci nie wysycą zasobów na maszynie, z której wystawiony jest interfejs dla funkcji R i czy może trzeba zapewnić jakiś mechanizm kolejkowania wywołań.
  3. Jaki będzie model wywołania: synchroniczny czy asynchroniczny i jaki będzie model pobierania odpowiedzi: polling, callback?
  4. Jak bardzo wydajne to ma być rozwiązanie (jak często będą wywołania, ile tych wywołań, jaki wymagany czas odpowiedzi) ?

Wymagania co do tej funkcjonalności dają kontekst, w ramach, którego możesz ocenić, że wybrane rozwiązanie jest lepsze od innego, np. binarny protokół lepszy bo walczymy o przepustowość łącza (bo płacimy za każdy odebrany/wysłany Gb i mamy tysiące wywołań), albo web servis będzie lepszy bo użytkownicy mogą prosto wygenerować klienta w oparciu o dostarczonego wsdla.

Od strony praktycznej, jak nie masz żadnych argumentów na stosowanie protokołu binarnego, to go nie stosuj, chyba że robisz ćwiczenie z programowania sieciowego i Wireshark jest Twoim ulubionym narzędziem ;-)

0

Jeżeli ruch sieciowy będzie wąskim gardłem to protokół binaryny albo RPC może pomóc z opóźnieniami. Jeżeli to obliczenia będą wąskim gardłem a późnienia nie mają znaczenia, to używając portokołu binarnego niepotrzebnie komplikujesz sprawę.

hauleth napisał(a):

Ja bym jednak zaproponował ProtoBuf od Google. Wsparcie języków dość dobre, a zdecydowanie lepiej przemyślane niż Corba. Ewentualnie Cap'n'proto, ale tu wsparcie jest już słabsze.

Ja bym wybrał gRPC od Googla albo thrift od Facebooka. Udostępnisz IDLa i każdy sobie wygeneruje odpowiedniego klienta. Sprawdź tylko bindingi języków, które Cię interesują.

Shalom napisał(a):

Z podobnych powodów Webservices wyparły praktycznie całkowicie rozwiązania w stylu CORBA już dawno temu, mimo że te drugie niby oferowały szybsze działanie (mocna kompresja danych) i więcej możliwości (asynchroniczność np.) i miały gotowe bindingi do wielu technologii.

Akurat CORBA jest cieżka, nadmiernie skomplikowana, stworozna przez komitet, niepotrzebnie starająca się zaspokoić wszystkie potrzeby, do tego obiektowa, podczs gdy obecne frameworki RPC zdają się preferować podejście operte na serwisach.

0
  1. Czy ta funkcjonalność wołania funkcji w R jest bezpieczna z perspektywy używania przez wielu klientów "jednocześnie"? Czy może trzeba zapewnić jakiś mechanizm synchronizacji?

Nie trzeba. Bezstanowe funkcje. OpenCPU zapewnia kompletną izolację użytkowników.

  1. Czy klienci nie wysycą zasobów na maszynie, z której wystawiony jest interfejs dla funkcji R i czy może trzeba zapewnić jakiś mechanizm kolejkowania wywołań.

Nie. Spodziewam się góra kilkunastu użytkowników pracujących równolegle. Zespół jest duży, ale specyfika pracy dokładnie taka, że nie muszę się tym przejmować. Serwer ma takie zasoby, że spokojnie obsłuży i 200 użytkowników przy założeniu, że proces R ma jakieś 50MB ze wszystkim co trzeba. Rdzeni też jest sporo, najwyżej czas wykonania wydłuży się z kilku sekund do kilkudziesięciu sekund, co jest wartością śmiesznie małą w porównaniu z tym, ile czasu zajmowały pewne obliczenia do dnia dzisiejszego, tj. kilka dni ciągłego ślęczenia nad Excelem.

  1. Jaki będzie model wywołania: synchroniczny czy asynchroniczny i jaki będzie model pobierania odpowiedzi: polling, callback?

Synchroniczny.

  1. Jak bardzo wydajne to ma być rozwiązanie (jak często będą wywołania, ile tych wywołań, jaki wymagany czas odpowiedzi) ?

Raczej niewymagające czasowo. Wywołań kilkadziesiąt w ciągu dnia, czasem co sekundę, czasem co parę godzin. Maksymalny akceptowalny czas odpowiedzi to jakieś 10-15 minut. Średni czas odpowiedzi dla jednego użytkownika obecnie to 7sek.

Wymagania co do tej funkcjonalności dają kontekst, w ramach, którego możesz ocenić, że wybrane rozwiązanie jest lepsze od innego, np. binarny protokół lepszy bo walczymy o przepustowość łącza (bo płacimy za każdy odebrany/wysłany Gb i mamy tysiące wywołań), albo web servis będzie lepszy bo użytkownicy mogą prosto wygenerować klienta w oparciu o dostarczonego wsdla.

Tak, masz rację. Jedyny problem tutaj to nie tyle zajętość serwera, co nieco ograniczona przepustowość sieci - duża firma i masa danych po niej biega. A te funkcje R zwracają duże tablice i spore dokumenty Excela i PDFy. Problemem jest to, że nazwy kolumn są opisowe. W przypadku XMLa to już rzeźnia, masakra jakaś, bo każda liczba będzie opatrzona nie tylko etykietą, ale dwiema etykietami: <otwierająca> i </zamykająca>. Co prawda można stosować nazwy kolumn typu "1,2,3,4", a potem przesłać osobno "słownik nazw", ale to już dłubanina. JSON o niebo lepszy, ale nadal "123" to 3 bajty, zamiast 1.

Od strony praktycznej, jak nie masz żadnych argumentów na stosowanie protokołu binarnego, to go nie stosuj, chyba że robisz ćwiczenie z programowania sieciowego i Wireshark jest Twoim ulubionym narzędziem ;-)

Zdecydowanie nie. Dziękuję bardzo za wnikliwą analizę!

0
KaBoom napisał(a):

...

Tak, masz rację. Jedyny problem tutaj to nie tyle zajętość serwera, co nieco ograniczona przepustowość sieci - duża firma i masa danych po niej biega. A te funkcje R zwracają duże tablice i spore dokumenty Excela i PDFy. Problemem jest to, że nazwy kolumn są opisowe. W przypadku XMLa to już rzeźnia, masakra jakaś, bo każda liczba będzie opatrzona nie tylko etykietą, ale dwiema etykietami: <otwierająca> i </zamykająca>. Co prawda można stosować nazwy kolumn typu "1,2,3,4", a potem przesłać osobno "słownik nazw", ale to już dłubanina. JSON o niebo lepszy, ale nadal "123" to 3 bajty, zamiast 1.

Skoro sieć jest wąskim gardłem, to może logika powinna wyglądać tak:

  1. Klient woła usługę (via HTTP?) będącą fasadą do R
  2. Usługa woła funkcję w R
  3. Usługa (bądź serwer HTTP) kompresuje rezultat wywołania funkcji R i zwraca do klienta
    a) Kompresja na poziomie HTTP w oparciu o Accept-encoding (klient i serwer HTTP muszą to wspierać)
    b) Kompresja na poziomie aplikacji (API musi być zaprojektowane z myślą o takim rozwiązaniu)
  4. Klient dostaje paczkę z odpowiedzią i dekompresja:
    a) jest transparenta dla klienta, bo kompresja zachodzi między serwerem i klientem na warstwie HTTP
    b) API klienckie musi zrobić robi dekompresję otrzymanej paczki

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