SlideShare une entreprise Scribd logo
1  sur  63
Télécharger pour lire hors ligne
Map Reduce
взгляд вглубь

           Павел Мезенцев
  p.mezentsev@rambler-co.ru
План


●   Что такое MapReduce


●   Элементарные запросы


●   Алгоритмы машинного обучения
История MapReduce

2003 г. Презентация Google MapReduce

2005 г. Начало разработки Hadoop в Yahoo

2007 г. Первый “боевой” Hadoop в Yahoo (4 500 нод)

2011 г. Стабильный релиз Hadoop 1.0
Где используется
     Hadoop?
Из чего состоит Hadoop


Распределенная файловая система HDFS
●   Name Node
●   Data Node


Система вычислений MapReduce
●   Job Tracker
●   Task Tracker
Архитектура Hadoop
Парадигма MapReduce

●   Map
(k 1, v 1 )→list (k 2, v 2 )


●   Shuffle & sort


●   Reduce
(k 2 , list (v 2 ))→list (k 3, v 3 )
Свойства MapReduce



Отказоустойчивость
●   Репликация
●   Промежуточные данные хранятся на диске

Вычислительная эффективность
● Последовательная работа с диском
● Data Locality

● Speculative Execution
Элементарные операции


●   Filter
●   Sort
●   Aggregate
●   Join
Логи Апача

    ip - - [time] "GET url HTTP 1.0" responce size referrer "user agent"
234.248.187.116 - - [01/May/2012:00:11:14 +0400] "GET http://news.rambler.ru/84459.html HTTP 1.0" 200 3347 - "Mozilla/5.0 (Windows; I; Windows NT 5.1; ru; rv:1.9.2.1...
234.248.187.116 - - [01/May/2012:00:12:47 +0400] "GET http://news.rambler.ru/14545.html HTTP 1.0" 200 12905 http://news.rambler.ru/84459.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:15:39 +0400] "GET http://news.rambler.ru/92834.html HTTP 1.0" 200 13995 http://news.rambler.ru/14545.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:15:50 +0400] "GET http://news.rambler.ru/59243.html HTTP 1.0" 200 15434 http://news.rambler.ru/92834.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:16:22 +0400] "GET http://news.rambler.ru/26836.html HTTP 1.0" 200 19972 http://news.rambler.ru/59243.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:17:33 +0400] "GET http://news.rambler.ru/69898.html HTTP 1.0" 200 5339 http://news.rambler.ru/26836.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:19:01 +0400] "GET http://news.rambler.ru/33116.html HTTP 1.0" 200 17092 http://news.rambler.ru/69898.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:19:44 +0400] "GET http://news.rambler.ru/70344.html HTTP 1.0" 200 17505 http://news.rambler.ru/33116.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:22:29 +0400] "GET http://news.rambler.ru/36486.html HTTP 1.0" 200 5631 http://news.rambler.ru/70344.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:22:55 +0400] "GET http://news.rambler.ru/86889.html HTTP 1.0" 200 12829 http://news.rambler.ru/36486.html "Mozilla/5.0 (Windows; I...
234.248.187.116 - - [01/May/2012:00:24:30 +0400] "GET http://news.rambler.ru/92288.html HTTP 1.0" 200 2567 http://news.rambler.ru/86889.html "Mozilla/5.0 (Windows; I...
206.93.190.212 - - [01/May/2012:00:25:31 +0400] "GET http://news.rambler.ru/19636.html HTTP 1.0" 200 18800 - "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trid...
234.248.187.116 - - [01/May/2012:00:26:17 +0400] "GET http://news.rambler.ru/71652.html HTTP 1.0" 200 9754 http://news.rambler.ru/92288.html "Mozilla/5.0 (Windows; I...
206.93.190.212 - - [01/May/2012:00:26:22 +0400] "GET http://news.rambler.ru/77419.html HTTP 1.0" 200 13543 http://news.rambler.ru/19636.html "Mozilla/5.0 (compatible...
56.134.253.176 - - [01/May/2012:00:26:22 +0400] "GET http://news.rambler.ru/22870.html HTTP 1.0" 200 4941 - "Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us...
234.248.187.116 - - [01/May/2012:00:26:59 +0400] "GET http://news.rambler.ru/16899.html HTTP 1.0" 200 16334 http://news.rambler.ru/71652.html "Mozilla/5.0 (Windows; I...
56.134.253.176 - - [01/May/2012:00:27:19 +0400] "GET http://news.rambler.ru/75525.html HTTP 1.0" 200 19956 http://news.rambler.ru/22870.html "Mozilla/5.0 (iPad; U; C...
234.248.187.116 - - [01/May/2012:00:28:21 +0400] "GET http://news.rambler.ru/89381.html HTTP 1.0" 200 2163 http://news.rambler.ru/16899.html "Mozilla/5.0 (Windows; I...
206.93.190.212 - - [01/May/2012:00:28:53 +0400] "GET http://news.rambler.ru/51517.html HTTP 1.0" 200 4098 http://news.rambler.ru/77419.html "Mozilla/5.0 (compatible...
56.134.253.176 - - [01/May/2012:00:29:18 +0400] "GET http://news.rambler.ru/82514.html HTTP 1.0" 200 15383 http://news.rambler.ru/75525.html "Mozilla/5.0 (iPad; U; C...
206.93.190.212 - - [01/May/2012:00:30:15 +0400] "GET http://news.rambler.ru/16247.html HTTP 1.0" 200 15262 http://news.rambler.ru/51517.html "Mozilla/5.0 (compatible...
234.248.187.116 - - [01/May/2012:00:30:20 +0400] "GET http://news.rambler.ru/95348.html HTTP 1.0" 200 2282 http://news.rambler.ru/89381.html "Mozilla/5.0 (Windows; I...
206.93.190.212 - - [01/May/2012:00:30:42 +0400] "GET http://news.rambler.ru/77261.html HTTP 1.0" 200 2396 http://news.rambler.ru/16247.html "Mozilla/5.0 (compatible...
56.134.253.176 - - [01/May/2012:00:32:05 +0400] "GET http://news.rambler.ru/35353.html HTTP 1.0" 200 5436 http://news.rambler.ru/82514.html "Mozilla/5.0 (iPad; U; C...
206.93.190.212 - - [01/May/2012:00:32:42 +0400] "GET http://news.rambler.ru/94600.html HTTP 1.0" 200 13284 http://news.rambler.ru/77261.html "Mozilla/5.0 (compatible...
234.248.187.116 - - [01/May/2012:00:32:43 +0400] "GET http://news.rambler.ru/33780.html HTTP 1.0" 200 14543 http://news.rambler.ru/95348.html "Mozilla/5.0 (Windows; I...
206.93.190.212 - - [01/May/2012:00:32:58 +0400] "GET http://news.rambler.ru/63754.html HTTP 1.0" 200 7173 http://news.rambler.ru/94600.html "Mozilla/5.0 (compatible...
206.93.190.212 - - [01/May/2012:00:33:10 +0400] "GET http://news.rambler.ru/53586.html HTTP 1.0" 200 6737 http://news.rambler.ru/63754.html "Mozilla/5.0 (compatible...
234.248.187.116 - - [01/May/2012:00:34:27 +0400] "GET http://news.rambler.ru/66747.html HTTP 1.0" 200 4256 http://news.rambler.ru/33780.html "Mozilla/5.0 (Windows; I...
….................................................................................................................................................................................................................................................................................................
Filter

Только map стадия



Пример:
Найти все логи поисковых переходов
Пример Java кода


public static class FilterMapper extends Mapper <LongWritable, Text, Text, NullWritable>
{
  protected void map (LongWritable key, Text logLine, Context context) {

        ApacheLogLine apacheLogLine = new ApacheLogLine (logLine.toString ());

        if (apacheLogLine.getReferrer ().contains ("yandex.ru")) {
            context.write(logLine, NullWritable.get ());
        }
    }
}
Драйвер задачи

public class FilterPrimitive
{
  public static int main (String [] args) throws Exception
  {
    Job job = new Job ();
    job.setJarByClass(FilterPrimitive.class);
    job.setMapperClass(FilterMapper.class);

        job.setNumReduceTasks (0);

        job.setOutputKeyClass (Text.class);
        job.setOutputValueClass(NullWritable.class);

        FileInputFormat.addInputPath(job, new Path (args [0]));
        FileOutputFormat.setOutputPath(job, new Path (args [1]));

        int returnCode = job.waitForCompletion(true) ? 1 : 0;
        return returnCode;
    }
}
Sort

Используется 1 редьюсер



Пример:
отсортировать логи по IP
Пример Java кода

public static class SortMapper extends Mapper <LongWritable, Text, Text, NullWritable>
{
  @Override
  protected void map (LongWritable key, Text logLine, Context context)
  throws IOException, InterruptedException {
    context.write(logLine, NullWritable.get ());
  }
}

public static class SortReducer extends Reducer <Text, NullWritable, Text, NullWritable>
{
  @Override
  protected void reduce (Text logline, Iterable <NullWritable> clicks, Context context)
  throws IOException, InterruptedException {
    for (NullWritable click : clicks) {
       context.write(logline, click);
    }
  }
}
Aggregate

Map-Reduce операция общего вида



Пример:
посчитать число кликов, сделанных с
кажого из ip
Пример Java кода

public static class AggregateMapper extends Mapper <LongWritable, Text, Text, NullWritable>
{
  protected void map (LongWritable key, Text logLine, Context context) {
    ApacheLogLine apacheLogLine = new ApacheLogLine (logLine.toString ());
    context.write(new Text (apacheLogLine.getIp ()), NullWritable.get ());
  }
}


public static class AggregateReducer extends Reducer <Text, NullWritable, Text, LongWritable>
{
  protected void reduce (Text ip, Iterable <NullWritable> clicks, Context context) {
    int clicksCount = 0;
    for (NullWritable click : clicks) {
       clicksCount ++;
    }
    context.write (ip, new LongWritable (clicksCount));
  }
}
Join

Пример задачи:
  имея таблицу соотвия “IP–география”
  отфильтровать логи, сделанные
  с московских IPшников.


Как можно сделать Join при помощи MapReduce?
Join

Пример задачи:
     имея таблицу соотвия “IP–география”
     отфильтровать логи, сделанные
     с московских IPшников.


Как можно сделать Join при помощи MapReduce?

●   Map-Side Join
●   Reduce-Side Join
Join




MultipleInputs.addInputPath (conf,
                             hdfsPath,
                             TextInputFormat.class,
                             JoinMapper.class);
Пример Java кода

 Мапперы:
public static class Join1Mapper extends Mapper <LongWritable, Text, Text, Text>
{
  public void map (LongWritable lineNum, Text logLine, Context context) {
    ApacheLogLine apacheLogLine = new ApacheLogLine (logLine.toString ());
    context.write(new Text (apacheLogLine.getIp ()), new Text ("log:" + logLine.toString ()));
  }
}


public static class Join2Mapper extends Mapper <LongWritable, Text, Text, Text>
{
  protected void map (LongWritable key, Text logLine, Context context) {
    String [] fields = logLine.toString ().split ("t");
    context.write(new Text (fields [0]), new Text ("city_name:" + fields [1]));
  }
}
Пример Java кода
public static class JoinReducer extends Reducer <Text, Text, Text, NullWritable>
{
  protected void reduce (Text ip, Iterable <Text> logsAndGeo, Context context) {
    List <String> logsList = new LinkedList <String> ();
    boolean isChosenCity = false;

      while (logsAndGeo.hasNext()) {
        String logOrGeo = logsAndGeo.next ().toString ();
        if (logOrGeo == "city_name:Moscow") {
            isChosenCity = true;
        }
        else {
            logsList.add (logOrGeo.substring (5));
        }
      }

      if (isChosenCity) {
          for (String logLine : logsList) {
            context.write(new Text (logLine), NullWritable.get ());
          }
      }
  }
Языки высокого уровня


Apache Pig                        Apache Hive


                         vs

●   Скриптовый язык           ●   SQL подобный язык
●   Разработан в Yahoo        ●   Разработан в Facebook
Загрузка данных


  Apache Pig                              Apache Hive
logs = LOAD '/user/mezentsev/logs' as (   create table logs (
   ip:chararray,                             ip STRING,
   empty1:chararray,                         empty1 STRING,
   empty2:chararray,                         empty2 STRING,
   human_time:chararray,
   request:chararray,               vs       human_time STRING,
                                             request STRING,
   return_code:int,                          return_code INT,
   size:int,                                 size INT,
   referrer:chararray,                       referrer STRING,
   user_agent:chararray);                    user_agent STRING)
                                          LOCATION '/user/mezentsev/logs';
Фильтрация


  Apache Pig                  Apache Hive

filtered_logs = FILTER
logs by
                              select * from logs where
(referrer matches
'.*yandex.ru.*');
                         vs   referrer like "%yandex.ru%";

dump filtered_logs;
Сортировка


 Apache Pig                    Apache Hive
                               SELECT ip,
sorted_logs = ORDER
                                     human_time,
logs BY ip, human_time;
                                     request
dump sorted_logs;
                          vs   FROM logs ORDER BY
                               ip, human_time;
Агрегация


 Apache Pig                Apache Hive
logs_by_ip =               SELECT ip, count (1)
GROUP logs BY ip;          FROM logs
                           GROUP BY ip;
ip_clicks = FOREACH   vs
logs_by_ip generate
group, COUNT($1);

DUMP ip_clicks;
Join


 Apache Pig                      Apache Hive
moscow_geo = FILTER              SELECT logs.*
geo BY                           FROM logs
(city_name == 'Moscow');         join geo ON logs.ip = geo.ip
                            vs   WHERE
logs_with_geo = JOIN logs        geo.city_name = "Moscow";
BY ip, moscow_geo BY ip;

DUMP logs_with_geo;
Как обрабатывать
данные быстро?
Как обрабатывать
данные быстро?

●   2010 г. Google Dremel

●   2012 г. Cloudera Impala

●   2012 г. Amazon Redshift

●   2013 г. Apache Drill
Как обрабатывать
данные быстро?

●   SQL образный синтаксис запросов


●   Результаты вычислений “не большие”


●   Отсутствует отказоустойчивость
MPP Архитектура
Impala vs Hive



●Работают с одним хранилищем
метаданных

●Производительность Impala в 4-30 раз
больше
Часть II



 Машинное обучение на MapReduce
Что такое машинное
обучение?




 Алгоритмы искуственного интеллекта, способные
 обучаться [Wikipedia]
Классификация
Кластеризация
Регрессия
Рекомендации
Apache Mahout


●   появился в 2008 году
●   300 тыс. строк кода
●   означает “погонщик слона”
●   правильно произносить “махут”
●   вышла книга “Mahout in Action”
Реализованные
    алгоритмы
    Классификация                                    Кластеризация
●   Логистическая регрессия                      ●   К-средних
●   Байесовские классификаторы                   ●   Нечеткий алгоритм K-средних
●   Случайный лес                                ●   Минимизация ожидания
●   Скрытые марковские цепи                      ●   Minhash кластеризация

                                                     ….............




                                    А также
                    ●   Коллаборативная фильтрация
                    ●   Генетические алгоритмы
                    ●   Алгоритмы уменьшения размерностей
Машинное обучение
на MapReduce

●   статья “MapReduce for Machine
    Learning on Multicore” (2008)

●   Алгоритм должен быть представим
    в аддитивной форме по входным
    данным
Наивный Байес


               ()
                  (1)
                x
Признаки    x
            ⃗ = ...       Класс y = {0, 1}
                  (n)
                x
Формула Байеса:
                                       (1)       (n)
      (1)         (n)      P( x ,.... , x ∣ y)
P( y∣x , .... , x )=P ( y)      (1)       (n)
                            P(x ,.... , x )

Наивное предположение:



        ∣x (1) ,.... , x (n))=P ( y)
                                       ∏i P(x (i)∣ y )
    P( y
                                             С
Наивный Байес
на MapReduce 1
                         ν( y) ∑ j 1( y j = y)
●   Выражение     P( y)=        =
                         ν(all)    ∑1           j




●   Map: выдаем         ( y j , Σ s ub ) (total , Σ s ub )


●   Reduce: выдаем      ( y j , Σ)       (total , Σ)
Наивный Байес
на MapReduce 2
                                               (i)
    Выражение             (i)         ν( x , y)
●
                     P( x ∣ y)=
                                        ν( y )



●   Map: выдаем      ((x i , y j ); Σ s ub )


●   Reduce: выдаем    ((x i , y j ); Σ)
Кластеризация K средних
Реализация на
MapReduce

Отнесение объектов к кластерам
 Map: выдаем      ( x , y nearest )


Поиск новых центров кластеров
  Map: выдаем            ( y j ,(Σs ub x , N ))

 Reduce: выдаем ( y j , x)
Логистическая
регрессия
Вероятность класса
                       1
        P w ( x)=
                  1+exp(−w⋅x)
Максимум
правдоподобия

                       yi             1− y i
Lw ( x)= ∏i P w ( x i ) (1−P w ( x i ))

           n
l(w)=∑i=1 y i log p ( x i )+(1− y i )log(1− p ( x i ))

w=argmax w l (w )
Метод
Ньютона-Рафсона
В скалярном виде:    В векторном виде

      l ' (w)                  −1
w=w−                 w=w−H ∇ w l(w)
     l ' ' (w)
                               2           2




             ( ) (                                  )
            ∂ l(w)        ∂ l(w)         ∂ l(w)
                                    ...
             ∂ w1        ∂ w1 ∂ w1      ∂ w1 ∂ wn
  ∇ w l(w )= ...      H=     ...    ...     ...
            ∂ l(w)         2
                          ∂ l(w)
                                          2
                                         ∂ l(w)
                                    ...
             ∂ wn        ∂ w n ∂ w1     ∂ wn ∂ wn
MapReduce
для Градиента
    Выражение            ∂ l(w )   m
                                 =∑i=1 ( y i − p w (x i )) x i
●                                                            (k)
                          ∂ wk


    Map: вычисляем      grad s ub [k ]=∑i ( y− pw ( x i )) x
●                                                              (k i )


        выдаем
                        (k , grad s ub [k ])

●   Reduce: вычисляем   grad [k ]=∑ grad s ub [k ]
           выдаем       (k , grad [k ])
MapReduce для
Гамильтониана
                        2
               ∂ l(w)      m
                         =∑i=1 p w (x i )( p w ( x i )−1) x i x i
                                                           ( j) (k)
●   Выражение
              ∂ wk ∂ w j


●   Map: вычисляем              H s ub [k , j]=∑s ub ....
           выдаем               ((k , j); H s ub [k , j])

●   Reduce: вычисляем H [k , j]=H s ub [k , j]
            выдаем    ((k , j); H [k , j])
Асимптотика
Алгоритм        Классическая   Сложность MapReduce
                сложность

                                   mn
Наивный Байес   O(mn+nc)        O(    +nc log P)
                                    P
                                   mnc
K-средних       O(mnc)          O(     +mn log P)
                                    P
                                    2    3
                      2   3        m n n
Логистическая   O(mn +n )       O(     + +n2 log P)
регрессия                           P   P

n – размерность пространства признаков
m – число обучающих примеров
P – число ядер, на которых делается обучение
Недостаток
Недостаток


  Итерационные алгоритмы
  машинного обучения читают
  с диска раз за разом одну и
  ту же обучающую выборку,
  что приводит к большим
  накладным расходам
Vowpal Wabbit




● Проект написан на C++
● Начат в 2007 году в Yahoo

● Сейчас разрабатывается

  в MicrosoftResearch
Предложенное решение

●   Итерационые алгоритмы должны обучаться
    в одну map-стадию

●   Все данные загружаются в оперативную память
    мапперов

●   Мапперы “находят” друг друга. Выстраиваются
    в бинарное дерево

●   Взаимодействие через операцию AllReduce
AllReduce: sum - 1


                 1

         2               3

    4        5       6       7
AllReduce: sum - 2



                  1

         11               16

     4        5       6        7
AllReduce: sum - 3



                   28

          11                16

     4         5        6        7
AllReduce: sum - 4



                28

         28               28

    28     28        28        28
Реализованные алгоритмы


●   Метод сопряженных градиентов

●   LBFGS

Contenu connexe

Similaire à MapReduce взгляд вглубь

CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDBCodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDBCodeFest
 
Серверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDBСерверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDBStepan Stolyarov
 
Expert Fridays Spark Job
Expert Fridays Spark JobExpert Fridays Spark Job
Expert Fridays Spark JobProvectus
 
Phalcon - самый быстрый PHP Framework
Phalcon - самый быстрый PHP FrameworkPhalcon - самый быстрый PHP Framework
Phalcon - самый быстрый PHP FrameworkOleksandr Torosh
 
Hadoop presentation
Hadoop presentationHadoop presentation
Hadoop presentationVlad Orlov
 
Rich UI on Dojo Toolkit and Zend Framework
Rich UI on Dojo Toolkit and Zend FrameworkRich UI on Dojo Toolkit and Zend Framework
Rich UI on Dojo Toolkit and Zend FrameworkGeorgy Turevich
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPITimur Shemsedinov
 
Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxYandex
 
Интеграция Яндекс Сервер
Интеграция Яндекс СерверИнтеграция Яндекс Сервер
Интеграция Яндекс СерверPVasili
 
MongoDB basics in Russian
MongoDB basics in RussianMongoDB basics in Russian
MongoDB basics in RussianOleg Kachan
 
IT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчикаIT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчикаMikhail Chinkov
 
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)""Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"Artjoker
 
Mihail davidov js-ajax
Mihail davidov js-ajaxMihail davidov js-ajax
Mihail davidov js-ajaxYandex
 
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человекаNETFest
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node jsAlex Tumanoff
 
Web весна 2012 лекция 4
Web весна 2012 лекция 4Web весна 2012 лекция 4
Web весна 2012 лекция 4Technopark
 

Similaire à MapReduce взгляд вглубь (20)

CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDBCodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
 
Серверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDBСерверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDB
 
Drupal Vs Other
Drupal Vs OtherDrupal Vs Other
Drupal Vs Other
 
Expert Fridays Spark Job
Expert Fridays Spark JobExpert Fridays Spark Job
Expert Fridays Spark Job
 
JSSDK: Начало
JSSDK: НачалоJSSDK: Начало
JSSDK: Начало
 
Phalcon - самый быстрый PHP Framework
Phalcon - самый быстрый PHP FrameworkPhalcon - самый быстрый PHP Framework
Phalcon - самый быстрый PHP Framework
 
Hadoop presentation
Hadoop presentationHadoop presentation
Hadoop presentation
 
Rich UI on Dojo Toolkit and Zend Framework
Rich UI on Dojo Toolkit and Zend FrameworkRich UI on Dojo Toolkit and Zend Framework
Rich UI on Dojo Toolkit and Zend Framework
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
Михаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, AjaxМихаил Давыдов — Транспорт, Ajax
Михаил Давыдов — Транспорт, Ajax
 
Интеграция Яндекс Сервер
Интеграция Яндекс СерверИнтеграция Яндекс Сервер
Интеграция Яндекс Сервер
 
MongoDB basics in Russian
MongoDB basics in RussianMongoDB basics in Russian
MongoDB basics in Russian
 
176023
176023176023
176023
 
IT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчикаIT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчика
 
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)""Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
 
Mihail davidov js-ajax
Mihail davidov js-ajaxMihail davidov js-ajax
Mihail davidov js-ajax
 
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
 
Jsfwdays 2013-2
Jsfwdays 2013-2Jsfwdays 2013-2
Jsfwdays 2013-2
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node js
 
Web весна 2012 лекция 4
Web весна 2012 лекция 4Web весна 2012 лекция 4
Web весна 2012 лекция 4
 

Plus de Pavel Mezentsev

Data science on big data. Pragmatic approach
Data science on big data. Pragmatic approachData science on big data. Pragmatic approach
Data science on big data. Pragmatic approachPavel Mezentsev
 
Курс "Хранение и Обработка больших данны". Лекция 5 YARN
Курс "Хранение и Обработка больших данны". Лекция 5 YARNКурс "Хранение и Обработка больших данны". Лекция 5 YARN
Курс "Хранение и Обработка больших данны". Лекция 5 YARNPavel Mezentsev
 
Слоны в облаках
Слоны в облакахСлоны в облаках
Слоны в облакахPavel Mezentsev
 
Илья Трофимов - машинное обучение с помощью vw
Илья Трофимов - машинное обучение с помощью vwИлья Трофимов - машинное обучение с помощью vw
Илья Трофимов - машинное обучение с помощью vwPavel Mezentsev
 
Мезенцев Павел - Машинное обучение на MapReduce
Мезенцев Павел - Машинное обучение на MapReduceМезенцев Павел - Машинное обучение на MapReduce
Мезенцев Павел - Машинное обучение на MapReducePavel Mezentsev
 

Plus de Pavel Mezentsev (6)

Data science on big data. Pragmatic approach
Data science on big data. Pragmatic approachData science on big data. Pragmatic approach
Data science on big data. Pragmatic approach
 
Yarn
YarnYarn
Yarn
 
Курс "Хранение и Обработка больших данны". Лекция 5 YARN
Курс "Хранение и Обработка больших данны". Лекция 5 YARNКурс "Хранение и Обработка больших данны". Лекция 5 YARN
Курс "Хранение и Обработка больших данны". Лекция 5 YARN
 
Слоны в облаках
Слоны в облакахСлоны в облаках
Слоны в облаках
 
Илья Трофимов - машинное обучение с помощью vw
Илья Трофимов - машинное обучение с помощью vwИлья Трофимов - машинное обучение с помощью vw
Илья Трофимов - машинное обучение с помощью vw
 
Мезенцев Павел - Машинное обучение на MapReduce
Мезенцев Павел - Машинное обучение на MapReduceМезенцев Павел - Машинное обучение на MapReduce
Мезенцев Павел - Машинное обучение на MapReduce
 

MapReduce взгляд вглубь

  • 1. Map Reduce взгляд вглубь Павел Мезенцев p.mezentsev@rambler-co.ru
  • 2. План ● Что такое MapReduce ● Элементарные запросы ● Алгоритмы машинного обучения
  • 3. История MapReduce 2003 г. Презентация Google MapReduce 2005 г. Начало разработки Hadoop в Yahoo 2007 г. Первый “боевой” Hadoop в Yahoo (4 500 нод) 2011 г. Стабильный релиз Hadoop 1.0
  • 5. Из чего состоит Hadoop Распределенная файловая система HDFS ● Name Node ● Data Node Система вычислений MapReduce ● Job Tracker ● Task Tracker
  • 7. Парадигма MapReduce ● Map (k 1, v 1 )→list (k 2, v 2 ) ● Shuffle & sort ● Reduce (k 2 , list (v 2 ))→list (k 3, v 3 )
  • 8. Свойства MapReduce Отказоустойчивость ● Репликация ● Промежуточные данные хранятся на диске Вычислительная эффективность ● Последовательная работа с диском ● Data Locality ● Speculative Execution
  • 9. Элементарные операции ● Filter ● Sort ● Aggregate ● Join
  • 10. Логи Апача ip - - [time] "GET url HTTP 1.0" responce size referrer "user agent" 234.248.187.116 - - [01/May/2012:00:11:14 +0400] "GET http://news.rambler.ru/84459.html HTTP 1.0" 200 3347 - "Mozilla/5.0 (Windows; I; Windows NT 5.1; ru; rv:1.9.2.1... 234.248.187.116 - - [01/May/2012:00:12:47 +0400] "GET http://news.rambler.ru/14545.html HTTP 1.0" 200 12905 http://news.rambler.ru/84459.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:15:39 +0400] "GET http://news.rambler.ru/92834.html HTTP 1.0" 200 13995 http://news.rambler.ru/14545.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:15:50 +0400] "GET http://news.rambler.ru/59243.html HTTP 1.0" 200 15434 http://news.rambler.ru/92834.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:16:22 +0400] "GET http://news.rambler.ru/26836.html HTTP 1.0" 200 19972 http://news.rambler.ru/59243.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:17:33 +0400] "GET http://news.rambler.ru/69898.html HTTP 1.0" 200 5339 http://news.rambler.ru/26836.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:19:01 +0400] "GET http://news.rambler.ru/33116.html HTTP 1.0" 200 17092 http://news.rambler.ru/69898.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:19:44 +0400] "GET http://news.rambler.ru/70344.html HTTP 1.0" 200 17505 http://news.rambler.ru/33116.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:22:29 +0400] "GET http://news.rambler.ru/36486.html HTTP 1.0" 200 5631 http://news.rambler.ru/70344.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:22:55 +0400] "GET http://news.rambler.ru/86889.html HTTP 1.0" 200 12829 http://news.rambler.ru/36486.html "Mozilla/5.0 (Windows; I... 234.248.187.116 - - [01/May/2012:00:24:30 +0400] "GET http://news.rambler.ru/92288.html HTTP 1.0" 200 2567 http://news.rambler.ru/86889.html "Mozilla/5.0 (Windows; I... 206.93.190.212 - - [01/May/2012:00:25:31 +0400] "GET http://news.rambler.ru/19636.html HTTP 1.0" 200 18800 - "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trid... 234.248.187.116 - - [01/May/2012:00:26:17 +0400] "GET http://news.rambler.ru/71652.html HTTP 1.0" 200 9754 http://news.rambler.ru/92288.html "Mozilla/5.0 (Windows; I... 206.93.190.212 - - [01/May/2012:00:26:22 +0400] "GET http://news.rambler.ru/77419.html HTTP 1.0" 200 13543 http://news.rambler.ru/19636.html "Mozilla/5.0 (compatible... 56.134.253.176 - - [01/May/2012:00:26:22 +0400] "GET http://news.rambler.ru/22870.html HTTP 1.0" 200 4941 - "Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us... 234.248.187.116 - - [01/May/2012:00:26:59 +0400] "GET http://news.rambler.ru/16899.html HTTP 1.0" 200 16334 http://news.rambler.ru/71652.html "Mozilla/5.0 (Windows; I... 56.134.253.176 - - [01/May/2012:00:27:19 +0400] "GET http://news.rambler.ru/75525.html HTTP 1.0" 200 19956 http://news.rambler.ru/22870.html "Mozilla/5.0 (iPad; U; C... 234.248.187.116 - - [01/May/2012:00:28:21 +0400] "GET http://news.rambler.ru/89381.html HTTP 1.0" 200 2163 http://news.rambler.ru/16899.html "Mozilla/5.0 (Windows; I... 206.93.190.212 - - [01/May/2012:00:28:53 +0400] "GET http://news.rambler.ru/51517.html HTTP 1.0" 200 4098 http://news.rambler.ru/77419.html "Mozilla/5.0 (compatible... 56.134.253.176 - - [01/May/2012:00:29:18 +0400] "GET http://news.rambler.ru/82514.html HTTP 1.0" 200 15383 http://news.rambler.ru/75525.html "Mozilla/5.0 (iPad; U; C... 206.93.190.212 - - [01/May/2012:00:30:15 +0400] "GET http://news.rambler.ru/16247.html HTTP 1.0" 200 15262 http://news.rambler.ru/51517.html "Mozilla/5.0 (compatible... 234.248.187.116 - - [01/May/2012:00:30:20 +0400] "GET http://news.rambler.ru/95348.html HTTP 1.0" 200 2282 http://news.rambler.ru/89381.html "Mozilla/5.0 (Windows; I... 206.93.190.212 - - [01/May/2012:00:30:42 +0400] "GET http://news.rambler.ru/77261.html HTTP 1.0" 200 2396 http://news.rambler.ru/16247.html "Mozilla/5.0 (compatible... 56.134.253.176 - - [01/May/2012:00:32:05 +0400] "GET http://news.rambler.ru/35353.html HTTP 1.0" 200 5436 http://news.rambler.ru/82514.html "Mozilla/5.0 (iPad; U; C... 206.93.190.212 - - [01/May/2012:00:32:42 +0400] "GET http://news.rambler.ru/94600.html HTTP 1.0" 200 13284 http://news.rambler.ru/77261.html "Mozilla/5.0 (compatible... 234.248.187.116 - - [01/May/2012:00:32:43 +0400] "GET http://news.rambler.ru/33780.html HTTP 1.0" 200 14543 http://news.rambler.ru/95348.html "Mozilla/5.0 (Windows; I... 206.93.190.212 - - [01/May/2012:00:32:58 +0400] "GET http://news.rambler.ru/63754.html HTTP 1.0" 200 7173 http://news.rambler.ru/94600.html "Mozilla/5.0 (compatible... 206.93.190.212 - - [01/May/2012:00:33:10 +0400] "GET http://news.rambler.ru/53586.html HTTP 1.0" 200 6737 http://news.rambler.ru/63754.html "Mozilla/5.0 (compatible... 234.248.187.116 - - [01/May/2012:00:34:27 +0400] "GET http://news.rambler.ru/66747.html HTTP 1.0" 200 4256 http://news.rambler.ru/33780.html "Mozilla/5.0 (Windows; I... ….................................................................................................................................................................................................................................................................................................
  • 11. Filter Только map стадия Пример: Найти все логи поисковых переходов
  • 12. Пример Java кода public static class FilterMapper extends Mapper <LongWritable, Text, Text, NullWritable> { protected void map (LongWritable key, Text logLine, Context context) { ApacheLogLine apacheLogLine = new ApacheLogLine (logLine.toString ()); if (apacheLogLine.getReferrer ().contains ("yandex.ru")) { context.write(logLine, NullWritable.get ()); } } }
  • 13. Драйвер задачи public class FilterPrimitive { public static int main (String [] args) throws Exception { Job job = new Job (); job.setJarByClass(FilterPrimitive.class); job.setMapperClass(FilterMapper.class); job.setNumReduceTasks (0); job.setOutputKeyClass (Text.class); job.setOutputValueClass(NullWritable.class); FileInputFormat.addInputPath(job, new Path (args [0])); FileOutputFormat.setOutputPath(job, new Path (args [1])); int returnCode = job.waitForCompletion(true) ? 1 : 0; return returnCode; } }
  • 15. Пример Java кода public static class SortMapper extends Mapper <LongWritable, Text, Text, NullWritable> { @Override protected void map (LongWritable key, Text logLine, Context context) throws IOException, InterruptedException { context.write(logLine, NullWritable.get ()); } } public static class SortReducer extends Reducer <Text, NullWritable, Text, NullWritable> { @Override protected void reduce (Text logline, Iterable <NullWritable> clicks, Context context) throws IOException, InterruptedException { for (NullWritable click : clicks) { context.write(logline, click); } } }
  • 16. Aggregate Map-Reduce операция общего вида Пример: посчитать число кликов, сделанных с кажого из ip
  • 17. Пример Java кода public static class AggregateMapper extends Mapper <LongWritable, Text, Text, NullWritable> { protected void map (LongWritable key, Text logLine, Context context) { ApacheLogLine apacheLogLine = new ApacheLogLine (logLine.toString ()); context.write(new Text (apacheLogLine.getIp ()), NullWritable.get ()); } } public static class AggregateReducer extends Reducer <Text, NullWritable, Text, LongWritable> { protected void reduce (Text ip, Iterable <NullWritable> clicks, Context context) { int clicksCount = 0; for (NullWritable click : clicks) { clicksCount ++; } context.write (ip, new LongWritable (clicksCount)); } }
  • 18. Join Пример задачи: имея таблицу соотвия “IP–география” отфильтровать логи, сделанные с московских IPшников. Как можно сделать Join при помощи MapReduce?
  • 19. Join Пример задачи: имея таблицу соотвия “IP–география” отфильтровать логи, сделанные с московских IPшников. Как можно сделать Join при помощи MapReduce? ● Map-Side Join ● Reduce-Side Join
  • 20. Join MultipleInputs.addInputPath (conf, hdfsPath, TextInputFormat.class, JoinMapper.class);
  • 21. Пример Java кода Мапперы: public static class Join1Mapper extends Mapper <LongWritable, Text, Text, Text> { public void map (LongWritable lineNum, Text logLine, Context context) { ApacheLogLine apacheLogLine = new ApacheLogLine (logLine.toString ()); context.write(new Text (apacheLogLine.getIp ()), new Text ("log:" + logLine.toString ())); } } public static class Join2Mapper extends Mapper <LongWritable, Text, Text, Text> { protected void map (LongWritable key, Text logLine, Context context) { String [] fields = logLine.toString ().split ("t"); context.write(new Text (fields [0]), new Text ("city_name:" + fields [1])); } }
  • 22. Пример Java кода public static class JoinReducer extends Reducer <Text, Text, Text, NullWritable> { protected void reduce (Text ip, Iterable <Text> logsAndGeo, Context context) { List <String> logsList = new LinkedList <String> (); boolean isChosenCity = false; while (logsAndGeo.hasNext()) { String logOrGeo = logsAndGeo.next ().toString (); if (logOrGeo == "city_name:Moscow") { isChosenCity = true; } else { logsList.add (logOrGeo.substring (5)); } } if (isChosenCity) { for (String logLine : logsList) { context.write(new Text (logLine), NullWritable.get ()); } } }
  • 23. Языки высокого уровня Apache Pig Apache Hive vs ● Скриптовый язык ● SQL подобный язык ● Разработан в Yahoo ● Разработан в Facebook
  • 24. Загрузка данных Apache Pig Apache Hive logs = LOAD '/user/mezentsev/logs' as ( create table logs ( ip:chararray, ip STRING, empty1:chararray, empty1 STRING, empty2:chararray, empty2 STRING, human_time:chararray, request:chararray, vs human_time STRING, request STRING, return_code:int, return_code INT, size:int, size INT, referrer:chararray, referrer STRING, user_agent:chararray); user_agent STRING) LOCATION '/user/mezentsev/logs';
  • 25. Фильтрация Apache Pig Apache Hive filtered_logs = FILTER logs by select * from logs where (referrer matches '.*yandex.ru.*'); vs referrer like "%yandex.ru%"; dump filtered_logs;
  • 26. Сортировка Apache Pig Apache Hive SELECT ip, sorted_logs = ORDER human_time, logs BY ip, human_time; request dump sorted_logs; vs FROM logs ORDER BY ip, human_time;
  • 27. Агрегация Apache Pig Apache Hive logs_by_ip = SELECT ip, count (1) GROUP logs BY ip; FROM logs GROUP BY ip; ip_clicks = FOREACH vs logs_by_ip generate group, COUNT($1); DUMP ip_clicks;
  • 28. Join Apache Pig Apache Hive moscow_geo = FILTER SELECT logs.* geo BY FROM logs (city_name == 'Moscow'); join geo ON logs.ip = geo.ip vs WHERE logs_with_geo = JOIN logs geo.city_name = "Moscow"; BY ip, moscow_geo BY ip; DUMP logs_with_geo;
  • 30. Как обрабатывать данные быстро? ● 2010 г. Google Dremel ● 2012 г. Cloudera Impala ● 2012 г. Amazon Redshift ● 2013 г. Apache Drill
  • 31. Как обрабатывать данные быстро? ● SQL образный синтаксис запросов ● Результаты вычислений “не большие” ● Отсутствует отказоустойчивость
  • 33. Impala vs Hive ●Работают с одним хранилищем метаданных ●Производительность Impala в 4-30 раз больше
  • 34. Часть II Машинное обучение на MapReduce
  • 35. Что такое машинное обучение? Алгоритмы искуственного интеллекта, способные обучаться [Wikipedia]
  • 40. Apache Mahout ● появился в 2008 году ● 300 тыс. строк кода ● означает “погонщик слона” ● правильно произносить “махут” ● вышла книга “Mahout in Action”
  • 41. Реализованные алгоритмы Классификация Кластеризация ● Логистическая регрессия ● К-средних ● Байесовские классификаторы ● Нечеткий алгоритм K-средних ● Случайный лес ● Минимизация ожидания ● Скрытые марковские цепи ● Minhash кластеризация …............. А также ● Коллаборативная фильтрация ● Генетические алгоритмы ● Алгоритмы уменьшения размерностей
  • 42. Машинное обучение на MapReduce ● статья “MapReduce for Machine Learning on Multicore” (2008) ● Алгоритм должен быть представим в аддитивной форме по входным данным
  • 43. Наивный Байес () (1) x Признаки x ⃗ = ... Класс y = {0, 1} (n) x Формула Байеса: (1) (n) (1) (n) P( x ,.... , x ∣ y) P( y∣x , .... , x )=P ( y) (1) (n) P(x ,.... , x ) Наивное предположение: ∣x (1) ,.... , x (n))=P ( y) ∏i P(x (i)∣ y ) P( y С
  • 44. Наивный Байес на MapReduce 1 ν( y) ∑ j 1( y j = y) ● Выражение P( y)= = ν(all) ∑1 j ● Map: выдаем ( y j , Σ s ub ) (total , Σ s ub ) ● Reduce: выдаем ( y j , Σ) (total , Σ)
  • 45. Наивный Байес на MapReduce 2 (i) Выражение (i) ν( x , y) ● P( x ∣ y)= ν( y ) ● Map: выдаем ((x i , y j ); Σ s ub ) ● Reduce: выдаем ((x i , y j ); Σ)
  • 47. Реализация на MapReduce Отнесение объектов к кластерам Map: выдаем ( x , y nearest ) Поиск новых центров кластеров Map: выдаем ( y j ,(Σs ub x , N )) Reduce: выдаем ( y j , x)
  • 49. Вероятность класса 1 P w ( x)= 1+exp(−w⋅x)
  • 50. Максимум правдоподобия yi 1− y i Lw ( x)= ∏i P w ( x i ) (1−P w ( x i )) n l(w)=∑i=1 y i log p ( x i )+(1− y i )log(1− p ( x i )) w=argmax w l (w )
  • 51. Метод Ньютона-Рафсона В скалярном виде: В векторном виде l ' (w) −1 w=w− w=w−H ∇ w l(w) l ' ' (w) 2 2 ( ) ( ) ∂ l(w) ∂ l(w) ∂ l(w) ... ∂ w1 ∂ w1 ∂ w1 ∂ w1 ∂ wn ∇ w l(w )= ... H= ... ... ... ∂ l(w) 2 ∂ l(w) 2 ∂ l(w) ... ∂ wn ∂ w n ∂ w1 ∂ wn ∂ wn
  • 52. MapReduce для Градиента Выражение ∂ l(w ) m =∑i=1 ( y i − p w (x i )) x i ● (k) ∂ wk Map: вычисляем grad s ub [k ]=∑i ( y− pw ( x i )) x ● (k i ) выдаем (k , grad s ub [k ]) ● Reduce: вычисляем grad [k ]=∑ grad s ub [k ] выдаем (k , grad [k ])
  • 53. MapReduce для Гамильтониана 2 ∂ l(w) m =∑i=1 p w (x i )( p w ( x i )−1) x i x i ( j) (k) ● Выражение ∂ wk ∂ w j ● Map: вычисляем H s ub [k , j]=∑s ub .... выдаем ((k , j); H s ub [k , j]) ● Reduce: вычисляем H [k , j]=H s ub [k , j] выдаем ((k , j); H [k , j])
  • 54. Асимптотика Алгоритм Классическая Сложность MapReduce сложность mn Наивный Байес O(mn+nc) O( +nc log P) P mnc K-средних O(mnc) O( +mn log P) P 2 3 2 3 m n n Логистическая O(mn +n ) O( + +n2 log P) регрессия P P n – размерность пространства признаков m – число обучающих примеров P – число ядер, на которых делается обучение
  • 56. Недостаток Итерационные алгоритмы машинного обучения читают с диска раз за разом одну и ту же обучающую выборку, что приводит к большим накладным расходам
  • 57. Vowpal Wabbit ● Проект написан на C++ ● Начат в 2007 году в Yahoo ● Сейчас разрабатывается в MicrosoftResearch
  • 58. Предложенное решение ● Итерационые алгоритмы должны обучаться в одну map-стадию ● Все данные загружаются в оперативную память мапперов ● Мапперы “находят” друг друга. Выстраиваются в бинарное дерево ● Взаимодействие через операцию AllReduce
  • 59. AllReduce: sum - 1 1 2 3 4 5 6 7
  • 60. AllReduce: sum - 2 1 11 16 4 5 6 7
  • 61. AllReduce: sum - 3 28 11 16 4 5 6 7
  • 62. AllReduce: sum - 4 28 28 28 28 28 28 28
  • 63. Реализованные алгоритмы ● Метод сопряженных градиентов ● LBFGS