Tuesday, 27 August 2013

Пост 18. Hadoop + RDBMS. Как прочитать данные из Hadoop через базу данных Oracle RDBMS.
OSCH.

"А зачем нужна дорога, если через неё нельзя перевести бабку" (С). 
Hadoop как много в этом звуке для седрца моего слилось... Но не будем забывать, что существуют конкретные технологии, которые сильны на определенных операциях. На других операциях они могут проигрывать. Слон не исключение. Так он откровенно проигрывает на большом колличестве низколатентных одновременных операций, которые по сути своей индекс ориентированы.
Что же делать? Использовать более подходящие технологии, например Oracle RDBMS. Для перегонки данных из hadoop в Oracle RDBMS существует множество способов. Один из них я опишу сегодня. Итак, название этому способу OSCH (Oracle SQL Connector for HDFS). Взять его можно здесь. Замечательная документация располагается здесь. Что же такое OSCH и когда его надо использовать? 

Oracle SQL Connector для HDFS является высокоскоростным коннектором для доступа к данным HDFS непосредственно из Oracle Database. 

Oracle SQL  onnector for HDFS позволяет осуществлять импорт данных из HDFS в любое время, по запросу приложений работающих с базой данных Oracle. Такой подход позволяет использовать стандартный SQL для доступа к данным HDFS, осуществлять связь с транзакционными таблицами Oracle DB. 

При доступе к HDFS осуществляется балансировка нагрузки между узалми. Данные хранящиеся на HDFS должны содержать файлы с разделителями или oracle data pump файлы созданные с помощью Oracle Loader for Hadoop.


В основу этого прложен механизм внешних таблиз Oracle (External table). Этот механизм позволяет читать плоские файлы с разделителями через SQL интерфейс. В версии 11.2 появилась новая фича - препроцессор, т.е. я могу выполнить некую команду перед чтением данных. Например, если у меня лежит zip файл и  мне его надо загрузить в СУБД (insert ... select ), я могу в качестве пропроцессора объявить unzip, а в качестве аргумента зипованный файл.Файл будет раззипован и поток данных пойдет в PGA. Этот механизм и положен в основу OSCH. Пропроцессором является некая программа, написанная Oracle которая читает файл (объявленный в location) и гонит поток данных в PGA. Итак, что нам необходимо для использования этого коннктора.
1) Подготовить среду на серере СУБД
2) С помощью инструментов OSCH создать внешнюю таблицу
3) Используя SQL интерфейс получить доступ к данным.

Установка:
[oracle@db11203x64 ~]$ sudo mkdir /u01/connectors
[oracle@db11203x64 ~]$ sudo chown oracle:dba /u01/connectors
[oracle@db11203x64 ~]$ cp oraosch-2.1.0.zip /u01/connectors
[oracle@db11203x64 ~]$ cd /u01/connectors
[oracle@db11203x64 connectors]$ unzip oraosch-2.1.0.zip
[oracle@db11203x64 connectors]$ unzip orahdfs-2.1.0.zip
[oracle@db11203x64 orahdfs-2.1.0]$ export OSCH_HOME=/u01/connectors/orahdfs-2.1.0
[oracle@db11203x64 orahdfs-2.1.0]$ echo "export OSCH_HOME=/u01/connectors/orahdfs-2.1.0" >> ~/.bash_profile
add OSCH_HOME=/u01/connectors/orahdfs-2.1.0 in /u01/connectors/orahdfs-2.1.0/bin/hdfs_stream
[root@db11203x64 ~]# yum install hadoop-client.noarch
[oracle@db11203x64 osch]$ export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/u01/app/oracle/product/11.2.0/db/jdbc/lib/ojdbc6.jar
[oracle@db11203x64 osch]$ echo "export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/u01/app/oracle/product/11.2.0/db/jdbc/lib/ojdbc6.jar" >> ~/.bash_profile
[root@db11203x64 ~]# yum install -y hive
[root@db11203x64 ~]# yum install -y hive-server
[oracle@db11203x64 osch]$ export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/usr/lib/hive/lib/*
Создаю пользователя и наделяю его правами (это опционально, можно использовать существующего пользователя):
SQL> CREATE USER demouser IDENTIFIED BY welcome1
  2  DEFAULT tablespace users
  3  TEMPORARY tablespace temp
  4  quota unlimited ON users;
GRANT CONNECT, resource TO demouser;
GRANT create procedure TO demouser;
GRANT create session TO demouser;
GRANT create table TO demouser;
grant select any dictionary to demouser;
GRANT DEBUG CONNECT SESSION TO demouser;

[oracle@db11203x64 osch]$ mkdir /home/oracle/sh/osch/oracle_dir/
[oracle@db11203x64 osch]$ sqlplus / as sysdba
...
CREATE DIRECTORY HADOOP_DIR AS '/home/oracle/sh/osch/oracle_dir/'
GRANT WRITE ON DIRECTORY hadoop_dir TO demouser;
GRANT READ ON DIRECTORY hadoop_dir TO demouser;

CREATE DIRECTORY OSCH_BIN_PATH AS '/u01/connectors/orahdfs-2.1.0/bin/';
GRANT WRITE ON DIRECTORY OSCH_BIN_PATH TO demouser;
GRANT READ ON DIRECTORY OSCH_BIN_PATH TO demouser;
GRANT EXECUTE ON DIRECTORY OSCH_BIN_PATH TO demouser;

Сгенерим файлик и закинем его на HDFS:

for i in `seq 1 100`; do echo 13`< /dev/urandom tr -dc 0-9 | head -c${1:-8};echo;` \
, 985`< /dev/urandom tr -dc 0-9 | head -c${1:-3};echo;`65` < /dev/urandom tr -dc 0-9 | head -c${1:-2};echo;` \
, 985`< /dev/urandom tr -dc 0-9 | head -c${1:-3};echo;`65` < /dev/urandom tr -dc 0-9 | head -c${1:-2};echo;`\
, 25001`< /dev/urandom tr -dc 0-9 | head -c${1:-8};echo;` \
, 3511`< /dev/urandom tr -dc 0-9 | head -c${1:-8};echo;` \
,  `< /dev/urandom tr -dc 0-9 | head -c${1:-2};echo;`,  `< /dev/urandom tr -dc 1-3 | head -c${1:-2};echo;` >> /tmp/test.cdr; done;
[oracle@db11203x64 osch]$ hadoop fs -mkdir /tmp/cdr_store/
[oracle@db11203x64 osch]$ hadoop fs -put /tmp/test.cdr /tmp/cdr_store/

Послле этого можно созать конфиг для OSCH:
<?xml version="1.0"?>
 <configuration>
    <property>
      <name>oracle.hadoop.exttab.tableName</name>
      <value>CDR_ON_HADOOP</value>
    </property>
    <property>
      <name>oracle.hadoop.exttab.locationFileCount</name>
      <value>4</value>
    </property>
    <property>
      <name>oracle.hadoop.exttab.dataPaths</name>
      <value>/tmp/cdr_store/*</value>
    </property>
    <property>
      <name>oracle.hadoop.exttabl.fieldTerminator</name>
      <value>,</value>
    </property>
    <property>
      <name>oracle.hadoop.exttab.defaultDirectory</name>
      <value>HADOOP_DIR</value>
    </property>
    <property>
      <name>oracle.hadoop.exttab.columnNames</name>
      <value>unixtime,a_num,b_num,imsi,imei,lac,rac</value>
    </property>
    <property>
      <name>oracle.hadoop.exttab.sourceType</name>
      <value>text</value>
    </property>
    <property>
      <name>oracle.hadoop.connection.url</name>
      <value>jdbc:oracle:thin:@//db11203x64:1521/orcl</value>
    </property>
    <property>
      <name>oracle.hadoop.connection.user</name>
      <value>demouser</value>
    </property>
</configuration>

И скрипт создания таблицы:
[oracle@db11203x64 osch]$ cat create_table.sh
#!/bin/bash
export OSCH_HOME="/u01/connectors/orahdfs-2.1.0"
hadoop jar $OSCH_HOME/jlib/orahdfs.jar \
       oracle.hadoop.exttab.ExternalTable \
       -conf create_table_conf.xml \
       -createTable

Запускаем create_table.sh и есть у нас счастье!
После создания таблицы можно проверить права следующей командой:
[oracle@db11203x64 ~]$ /u01/connectors/orahdfs-2.1.0/bin/hdfs_stream /home/oracle/sh/osch/oracle_dir/osch-20130717031307-3212-4
У меня был вывод на экран данных из фалов:
1384679623 , 9856406598 , 9850086592, 2500177363357 , 351133071222 , 35, 22
1390537385 , 9857676598 , 9858736550, 2500100777055 , 351184607283 , 82, 23
1335107726 , 9853106532 , 9852956508, 2500127223291 , 351145561629 , 57, 22

Если будут вопросы - не стесняйтесь задавать!

2 comments:

  1. Привет ! Есть очень простой вопрос от новичка :
    не хватает пошаговых рекомендаций как установливать и что устанавливать. Возможно это связано с тем что еще не понятна системная архитектура решения: это набор java программ ? кто ими управляет ? локальное файловое хранилище состоит из набора файлов или это единый файл? как бэкапить узел (нужно ли его бэкапить)? Можно ли клонировать узлы ? что для этого нужно сделать ? и тд. и тп.

    ReplyDelete
  2. На вопросы тут ещё отвечают или блог порос мохом?)

    ReplyDelete