Постоянно находящаяся в оперативной памяти база данных Oracle TimesTen всегда наготове.
За пару прошлых лет корпорация Oracle сделала несколько стратегических приобретений, и одним из наиболее интересных из них является постоянно находящаяся в оперативной памяти база данных, которая
называется TimesTen. База данных Oracle TimesTen позволяет разрабатывать в реальном времени стратегически важные приложения, в которых время реакции должно измеряться даже не миллисекундами, а
микросекундами. Она может использоваться автономно или как быстрый двунаправленный кэш для данных, к которым часто обращаются из Oracle Database.
Хорошим примером приложения, которое может многое выиграть от применения Oracle TimesTen, является диспетчерская система реагирования на чрезвычайные ситуации, типа системы, к которой в США можно
подключиться, набирая номер 911. (Фактически, БД Oracle TimesTen уже развернута, по крайней мере, в одном из приложений, связанных со службой 911.) Время ответа в таких системах является более чем
критическим; это – вопрос жизни и смерти.
Когда в большинстве регионов США вы набираете номер 911, диспетчер сразу же видит на экране ваш номер телефона и адрес, а часто система предлагает карту, показывающую ваше местоположение и,
возможно, даже информацию об известных проблемах со здоровьем в вашем местоположении. Например, пациент с серьезной аллергией, которому прописано иметь при себе автоинжектор эпинэфрина, может
захотеть зарегистрировать эту информацию у диспетчеров группы реагирования на чрезвычайные ситуации. Немедленный доступ к адресу и другой критической информации является ключевым для быстрого
получения помощи.
В предлагаемой статье описывается реализация элементарной системы баз данных, которая могла бы использоваться для отображения критической информации диспетчерам группы реагирования на чрезвычайные
ситуации. Тем самым будет показано, как Oracle TimesTen может работать с Oracle Database, чтобы обеспечить надежное, порядка микросекунд, время отклика, гарантируя при этом, что критические данные
всегда будут немедленно доступными.
Архитектура
На рис. 1 изображено представление архитектуры, стоящей за Oracle TimesTen. В контексте Oracle TimesTen базу данных принято называть хранилищем данных. Представление хранилища данных на диске
называют файлом контрольной точки. Когда хранилище данных открывается в первый раз, все его содержимое считывается в память из файла контрольной точки. Последующие операции INSERT, DELETE, SELECT,
UPDATE и другие операции базы данных выполняются в памяти. Изменения хранилища данных, обусловленные выполнением этих операций, периодически и асинхронно записываются в дисковый файл контрольной
точки. Когда хранилище данных останавливается, любые остающиеся незаписанными изменения записываются в файл контрольной точки прежде, чем хранилище данных будет закрыто.
Рисунок 1. Архитектура Oracle TimesTen
Кроме того, Oracle TimesTen использует память на диске как механизм восстановления для защиты транзакций. Транзакции регистрируются в журналах. Если система “упала” и должна быть перезапущена,
файл контрольной точки будет прочитан в память, затем будут применены журналы транзакций и хранилище данных будет снова открыто для бизнес-деятельности. Периодическая запись изменений базы данных в
файл контрольной точки во время обычной деятельности сводит к минимуму время, необходимое для любой операции восстановления, которая могла бы произойти.
Как было только что описано, Oracle TimesTen может выполняться как автономная база данных, но при желании ее могло также выполнять как ускоритель производительности для данных, перемещаемых в/из
Oracle Database. На рис. 1 показан агент кэша и сервис тиражирования, который может подключить Oracle TimesTen к Oracle Database. В сценарии этой статьи некоторые данные хранятся в Oracle TimesTen,
как бы для иллюстрации автономного подхода, а другие данные хранятся в Oracle Database, чтобы проиллюстрировать повышение производительности. В случае необходимости вы можете объединить оба
подхода.
Создание базы данных Oracle TimesTen
Возможно выполнение Oracle TimesTen на нескольких платформах, в том числе, на различных дистрибутивах Linux, Windows XP и Windows Server 2003, Solaris и HP-UX. Руководство по инсталляции постоянно
находящейся в памяти базы данных Oracle TimesTen обеспечивает команды инсталляции для всех поддерживаемых платформ. Инсталляция Windows является очень простой, и именно ее использовали при выполнении
примера для этой статьи.
Доступ к Oracle TimesTen, в конечном счете, осуществляется через ODBC. (Приложения Java используют JDBC, а драйвер JDBC TimesTen, в свою очередь, использует ODBC.) Создание хранилища данных Oracle
TimesTen столь же просто, как определение источника данных ODBC и последующее соединение с ним. В целях этой статьи примем, что у вас имеется схема Oracle Database, которая называется DISPATCH, с
таблицами, указанными в листинге 1. Далее предположим, что вы установили Oracle TimesTen и ваше приложение для реагирования на чрезвычайные ситуации – то самое, которое сообщает критическую
информацию на сервер Windows, когда поступает запрос. Чтобы создать хранилище данных Oracle TimesTen для поддержки приложения для отправки и кэширования критических данных из Oracle Database
используйте следующие шаги:
Листинг 1. Схема DISPATCH в Oracle Database 10g
CREATE TABLE phones (
phone_num VARCHAR2(8),
street_addr VARCHAR2(20),
city VARCHAR2(15),
PRIMARY KEY (phone_num));
CREATE TABLE call_log (
call_num NUMBER(9),
event_time TIMESTAMP,
event VARCHAR2(80),
PRIMARY KEY (call_num, event_time));
GRANT SELECT, UPDATE, INSERT ON call_log TO ttdispatch;
INSERT INTO phones VALUES ('555-1234','100 W. Munising Ave', 'Munising');
INSERT INTO phones VALUES ('555-2345','101 E. Varnum', 'Munising');
INSERT INTO phones VALUES ('555-3456','E2904 S. First', 'Trenary');
INSERT INTO phones VALUES ('555-4567','N3284 M-67', 'Limestone');
INSERT INTO phones VALUES ('555-5678','N7569 Spruce St.', 'AuTrain');
INSERT INTO phones VALUES ('555-6789','112 Colwell', 'Grand Marais');
COMMIT;
- Перейдите к панели управления (Control Panel) и откройте администратор источника данных ODBC (ODFBC Data Source Administrator). Выберите Старт -> Параметры настройки -> Панель
управления-> Инструментальные средства Администрирования -> Источники данных (ODBC) (Start -> Settings -> Control Panel -> Administrative Tools -> Data Sources (ODBC)).
- Добавьте системный источник данных, используя драйвер TimesTen Data Manager 6.0.
- Из вкладки Data Store (см. рис. 2) введите имя источника данных (DSN), путь к хранилищу данных и каталог с журнальными файлами. Путь к хранилищу данных должен заканчиваться именем файла без
указания расширения.
Рисунок 2. Настройка источника данных Oracle TimesTen
- Перейдите к вкладке General Connection, найдите поле User ID и введите имя пользователя Oracle Database, обладающего правами доступа к таблицам, перечисленным в Листинге 1. Здесь вы можете
использовать имя владельца схемы.
- Перейдите к вкладке Cache Connect, найдите там поле Oracle Password и введите пароль для имени пользователя, использованного на шаге 4. Затем найдите поле Oracle ID и введите имя сетевого сервиса
(из tnsnames.ora) для Oracle TimesTen для использования при соединении с Oracle Database.
- Нажмите OK, чтобы создать источник данных ODBC.
Примечание: при выполнении в среде Linux или других систем на основе UNIX, вы определяете источник данных путем редактирования файла .odbc.ini. Детали можно найти в
“Руководстве по эксплуатации Oracle TimesTen In-Memory Database”.
- Соединитесь с вашим недавно созданным источником данных ODBC, используя интерактивную SQL-утилиту Oracle TimesTen ttIsql (аналогичную SQL*Plus для Oracle Database). После этого выполните команду
CONNECT, чтобы открыть источник данных, создавая, таким образом, хранилище данных. Например:
C:\A>ttisql
Copyright (c) 1996-2006, Oracle.
.
.
.
Command> CONNECT dsn=ttdispatch;
.
.
.
Connection successful:
Теперь у вас в памяти имеется выполняющееся хранилище данных Oracle TimesTen. По умолчанию Oracle TimesTen автоматически создает хранилище данных, когда оно должно быть использовано в первый раз.
Чтобы увидеть перечень системных таблиц для этого хранилища данных, введите команду TABLES. Чтобы получить перечень всех доступных команд ttIsql, наберите HELP. Убедитесь, что после любой выполняемой
вами команды ttIsql вы не забыли набрать точку с запятой (;).
В вашем путевом каталоге хранилища данных (c:\a\timesten на рис. 2) вы будете видеть две копии файла контрольной точки с расширениями .ds0 и .ds1. Имя этих файлов – это то самое имя, которое вы
предоставили ранее на шаге 3. В вашем каталоге с журнальными файлами (также c:\a\timesten в этом примере), вы сможете увидеть журналы с расширением .log.
При использовании драйверов TimesTen Data Manager 6.0 (на шаге 2) вы даете вашему приложению возможность взаимодействовать непосредственно с хранилищем данных. Нет никаких контекстных
переключателей и никаких запросов, отсылаемых по сети – только прямой, быстрый доступ к данным. Несколько приложений, совместно использующих хранилище данных, пользуются общим доступом к хранилищу
данных через коллективный сегмент памяти.
По умолчанию Oracle TimesTen считывает все данные в память, когда первый пользователь соединяется с хранилищем данных, и записывает данные назад на диск, когда отключается последний пользователь.
Это один из способов приближения Oracle TimesTen к минимальному обслуживанию (Zero Maintenance). Однако и здесь у вас имеются дополнительные возможности. Например, можно сделать так, чтобы Oracle
TimesTen считывал хранилище данных в память сразу после запуска сервера, чтобы данные уже были там, когда подключится первый пользователь.
Создание таблиц
Таблица в Oracle TimesTen создается так же, как и в любой другой базе данных. Например, можно создать следующую таблицу, чтобы позволить постоянным жителям сделать записи данных, доступ к которым
может стать потенциально спасительным для диспетчеров в чрезвычайных ситуациях:
CREATE TABLE emergency_info (
phone_num VARCHAR(8),
info VARCHAR(160),
PRIMARY KEY (phone_num));
Теперь вы можете записать комментарии, которые могут оказаться полезными для диспетчеров и респондентов, оказавшихся в критическом положении:
INSERT INTO emergency_info
VALUES ('555-1234',
'Child Jeff allergic to egg white.
Epinephrine autoinjector in orange box
near refrigerator.');
INSERT INTO emergency_info
VALUES ('555-2345',
'Bedridden resident needs help
exiting home in case of fire.');
Типы данных Oracle TimesTen не совпадают в точности с типами данных из Oracle Database. Например, в Oracle TimesTen используется тип данных VARCHAR, а не VARCHAR2. См. документацию по Oracle
TimesTen In-Memory Database API и Справочное руководство по SQL, где можно найти подробную информацию о типах данных, включая то, как типы данных Oracle Database могут быть отображены на типы данных
Oracle TimesTen.
Кэширование данных “только для чтения”
Вероятно, данные о телефонных номерах и адресах в системах реагирования на чрезвычайные ситуации будут использоваться только для чтения. Вы хотите, чтобы для данного телефонного номера диспетчеры
видели связанный с ним адрес, но вы не хотите, чтобы те же самые диспетчеры отвлекались от своей работы при необходимости отредактировать информацию адреса. В таком случае разумно сделать для
диспетчеров таблицу TELEPHONES доступной только для чтения.
Прежде, чем будет создан кэш данных телефонов/адресов только для чтения, следует создать пользователя – администратора кэша в Oracle Database. Этот пользователь владеет триггерами и таблицами,
которые Oracle TimesTen создает в Oracle Database для отслеживания изменений в данных таким образом, чтобы они могли быть использованы для эффективного обновления кэшированных данных в Oracle
TimesTen. Например, войдя в систему как пользователь system, выполните следующий оператор, чтобы создать администратора кэша с именем ttdispatch:
CREATE USER ttdispatch
identified by ttdispatch
default tablespace users
quota unlimited on users;
Затем выполните следующие операции предоставления привилегий, чтобы позволить администратору кэша создавать триггеры для таблиц, принадлежащих другим пользователям (например, владельцу схемы
DISPATCH):
grant create any trigger to ttdispatch;
Затем войдите в систему, как владелец схемы отправки, и предоставьте администратору кэша доступ SELECT к таблице TELEPHONES:
GRANT SELECT ON phones TO ttdispatch;
Теперь переключитесь к Oracle TimesTen и создайте группу кэша. Чтобы сделать это:
- Находясь в ttIsql, соединитесь с вашим хранилищем данных.
- Сделайте вызов встроенной процедуры ttCacheUidPwdSet() и специфицируйте для Oracle TimesTen имя пользователя/пароль, чтобы использовать их при соединении с Oracle Database как администратор
кэша.
- Вызовите ttCacheStart(), чтобы запустить агент кэширования TimesTen, который является ответственным за выполнение фактической работы по поиску данных из Oracle Database и кэширование этих данных
в Oracle TimesTen.
- Выполните оператор CREATE CACHE GROUP, чтобы определить группу связанных таблиц – в этом случае, только одну таблицу – для кэширования в Oracle TimesTen.
В листинге 2 показаны все четыре этих шага.
Листинг 2. Создание группы кэша “только для чтения”
Command> connect dsn=ttdispatch;
Connection successful:
.
.
.
Command> call ttCacheUidPwdSet('ttdispatch','ttdispatch');
Command> call ttCacheStart();
Command>
Command> CREATE READONLY
> CACHE GROUP phone_data
> AUTOREFRESH
> INTERVAL 5 MINUTES
> FROM dispatch.phones (
> phone_num VARCHAR(8) NOT NULL PRIMARY KEY,
> street_addr VARCHAR(20),
> city VARCHAR(15)
> );
Warning 5112: Cache table DISPATCH.PHONES contains
VARCHAR column(s). Oracle VARCHAR comparison rule is different.
(Предупреждение 5112: Кэшированная таблица DISPATCH.PHONES содержит
столбец(цы) VARCHAR. Правила сравнения для VARCHAR в Oracle отличаются.)
Заметьте, что предупреждающее сообщение в конце листинга 2 служит напоминанием о том, что Oracle TimesTen считает пустую (незаполненную) строку (") не пустой (non-null), тогда как Oracle Database
трактует пустую (empty) строку как пустую (null). При написании запросов с участием столбцов VARCHAR вы должны обращать внимание на подобные различия в поведении.
Теперь у вас имеется группа кэша, названная phone_data. В составе этой группы имеется единственная пустая таблица по имени TELEPHONES. Для группы кэша устанавливается автоматическое обновление,
для чего с пятиминутным интервалом производится опрос Oracle Database относительно изменений в данных. Однако, такое автоматическое обновление первоначально выполняется в приостановленном состоянии
(во время паузы). Выполните оператор LOAD CACHE GROUP, показанный в листинге 3, чтобы инициализировать кэш текущими данными из Oracle Database и вывести группу кэша из паузы. Начиная с этого момента,
каждые пять минут Oracle TimesTen будет делать запросы к Oracle Database (вы можете указать большие или меньшие интервалы) об изменениях в таблице TELEPHONES. Триггеры и таблицы поддержки,
принадлежащие администратору кэша (в этом случае, ttdispatch) делают такой опрос весьма эффективным.
Листинг 3. Выполнение начальной загрузки
Command> SELECT * FROM phones;
0 rows found.
Command> LOAD CACHE GROUP phone_data
> COMMIT EVERY 100 ROWS;
6 rows affected.
Command> select * from phones;
< 555-1234, 100 W. Munising Ave, Munising >
< 555-2345, 101 E. Varnum, Munising >
< 555-3456, E2904 S. First, Trenary >
< 555-4567, N3284 M-67, Limestone >
< 555-5678, N7569 Spruce St., AuTrain >
< 555-6789, 112 Colwell, Grand Marais >
6 rows found.
Создание кэша со сквозной записью
Принимая во внимание, что источником данных о телефонах/адресах является Oracle Database, а адресатом – Oracle TimesTen, вы хотите, чтобы зарегистрированные данные текли в другом направлении.
Диспетчеры должны регистрировать события, имеющие отношение к звонкам в 911, в Oracle TimesTen. Однако, вы хотите, чтобы данные журнала были переданы для долгосрочного хранения в Oracle Database. С
этой целью можно создать асинхронную группу кэша со сквозной записью. В листинге 4 показан предназначенный для этой цели оператор Oracle TimesTen.
Листинг 4. Создание кэша со сквозной записью
CREATE ASYNCHRONOUS WRITETHROUGH
CACHE GROUP call_log_data
FROM dispatch.call_log (
call_num BIGINT,
event_time TIMESTAMP,
event VARCHAR(80),
PRIMARY KEY
(call_num,
event_time)
) UNIQUE HASH ON (call_num, event_time) PAGES=1000;
После создания группы, запустите сервис тиражирования Oracle TimesTen, вызывая для этого из ttIsql встроенную процедуру ttRepStart:
CALL ttRepStart();
Начиная с этого момента, все строки, которые ваше диспетчерское приложение вставляет в таблицу CALL_LOG Oracle TimesTen, будут вставлены в таблицу CALL_LOG в Oracle Database. Поскольку группа кэша
является асинхронной, Oracle TimesTen зафиксирует транзакции, использующие вставки в CALL_LOG, не дожидаясь, пока соответствующие вставки будут зафиксированы в Oracle Database. Если подключение к
Oracle Database будет прервано, то Oracle TimesTen будет отслеживать недавно вставленные записи журнала и отправлять их в Oracle Database, когда подключение будет установлено вновь.
Асинхронный кэш со сквозной записью дает вам лучшую производительность. Однако, вы можете создать синхронную группу кэша, если вы хотите гарантировать, что когда транзакция, использующая таблицу
CALL_LOG, фиксируется в Oracle TimesTen, любые изменения в таблице CALL_LOG будут также зафиксированы и в Oracle Database. Выбор полностью остается за вами и определяется только вашими деловыми
потребностями.
Ошибки при тиражировании
Если вы не проявите осторожность при проектировании своего приложения, то подвергнетесь риску, что попытка зафиксировать в Oracle Database вставки в таблицу CALL_LOG, которые были успешно
зафиксированы в Oracle TimesTen, потерпит неудачу. Любые такие ошибки тиражирования регистрируются в имеющем расширение .awterr асинхронном файле ошибок со сквозной записью, в том же самом каталоге,
в котором содержатся файлы контрольной точки.
Один из способов избежать проблем при тиражировании состоит в том, чтобы тщательно продумать, какая база данных будет "владельцем", или управляющей, для заданной таблицы или для набора из
связанных таблиц. В сценарии диспетчирования все вставки в таблицу CALL_LOG делаются в Oracle TimesTen. Не позволяется вносить никаких изменений данных со стороны Oracle Database. Таким образом, все
вставки должны распространяться из Oracle TimesTen в Oracle Database без ошибок.
Удаление устаревших записей
Таблица типа CALL_LOG будет постоянно расти. Вы не сможете сохранить всю таблицу подобного типа в размещенной в оперативной памяти базе данных. Вам придется предусмотреть условия, в соответствии с
которыми должна производиться очистка устаревших журнальных записей. Один из подходов, которым можно было бы воспользоваться, состоит в том, чтобы сохранять в Oracle TimesTen только записи журнала за
текущий день, оставляя Oracle Database всю работу по долговременному, архивному хранению. С этой целью можно ежедневно выполнять приведенный в листинге 5 оператор UNLOAD CACHE GROUP. Оператор удалит
из Oracle TimesTen все записи, кроме записей текущего дня, оставив при этом нетронутой таблицу CALL_LOG в Oracle Database. В таком случае диспетчеры смогут получить доступ к журнальным записям
текущего дня непосредственно из Oracle TimesTen. Любой из тех, кому потребуется просмотреть журнальные записи прошлых дней, может сделать запрос к Oracle Database.
Листинг 5. Удаление старых записей журналов
UNLOAD CACHE GROUP call_log_data
WHERE NOT(
EXTRACT(YEAR FROM EVENT_TIME) = EXTRACT(YEAR FROM SYSDATE)
AND EXTRACT(MONTH FROM EVENT_TIME) = EXTRACT(MONTH FROM SYSDATE)
AND EXTRACT(DAY FROM EVENT_TIME) = EXTRACT(DAY FROM SYSDATE)
);
Действительно ли память является ключом к решению всех проблем?
Поскольку Oracle TimesTen получает свое преимущество в производительности благодаря хранению всего хранилища данных в памяти, почему бы не попробовать просто запустить Oracle Database и
сконфигурировать буферный кэш настолько большим, чтобы он мог удержать в памяти всю базу данных? Разве в таком случае Oracle Database не будет работать точно так же, как Oracle TimesTen? Это хороший
и справедливый вопрос, достойный того, чтобы уделить ему внимание.
Продукт Oracle TimesTen с самого начала был спроектирован как размещающаяся в оперативной памяти база данных. В нем полностью отсутствует логический ввод/вывод в том смысле, который наличествует в
Oracle Database. Нет никаких блоков базы данных. Нет никакого буферного кэша. Статьи индекса вместо того, чтобы содержать идентификаторы логических строк, указывают непосредственно на адреса памяти,
где могут быть найдены эти целевые строки. Для перехода от статьи индекса к строке в Oracle TimesTen требуется простое разыменование указателя. Благодаря использованию драйверов TimesTen Data Manager
6.0, ваше приложение имеет прямой доступ к памяти, в которой хранятся данные; отпадает необходимость в каких-либо дорогостоящих контекстных переключателях.
Однако, память не является ключом к решению всех проблем. За последние несколько лет было написано очень много о ненулевой стоимости логического ввода/вывода в Oracle Database, и хотя Oracle
TimesTen может сделать стоимость обращения к находящимся в оперативной памяти данным намного более близкой к нулю, какая-то стоимость все таки остается. По-прежнему очень важен хороший дизайн.
По-прежнему остается применимой теория очередей. Все еще важна оптимизация производительности, чтобы сократить ненужную обработку.
Преимущества TimesTen
Гибкость Oracle TimesTen намного превышает то, что было здесь показано. Кроме того, с Oracle TimesTen
- Вы можете создавать кэши, в которые данные, при необходимости, вводятся автоматически, а затем удаляются после истечения заданного промежутка времени.
- Вы можете определить асинхронную регистрацию, или даже полное отсутствие регистрации вообще, обменивая долговечность на производительность.
- Вы можете использовать тиражирование из Oracle TimesTen в Oracle TimesTen, чтобы создавать резервные базы данных для обеспечения высокой доступности или для зеркалирования баз данных для
выравнивания загрузки.
- Вы можете автоматически пропускать запросы к Oracle Database, когда они обращаются к таблицам, найденным в Oracle Database, а не в Oracle TimesTen.
Если объединить ее с нормальной базой данных и хорошим дизайном приложения в оперативной памяти, производительность Oracle TimesTen делает возможной работу как стратегически важных, так и
критичных ко времени поддерживаемых базой данных приложений. Когда минимизация микросекунд может сэкономить деньги или жизни, может пригодиться Oracle TimesTen In-Memory Database.
Благодарю Сэма Дрейка (Sam Drake) и Саймона Лоу (Simon Law) из Oracle за их долготерпение при ответах на многочисленные вопросы относительно этой статьи. Отдельные благодарности отделу шерифа
округа Олжер, шт. Мичиган, за предоставление возможности детального знакомства с диспетчерским центром округа; а также службе скорой медицинской помощи округа Олжер, предложившей использованный в
этой статье сценарий примера.
Джонатан Генник (www.gennick.com) – опытный профессионал Oracle и зарегистрированный член сети Oak Table Network. Он написал пользующиеся
спросом книги – “Карманное руководство по SQL” и “Карманный справочник по Oracle SQL*Plus”, опубликованные издательством O'Reilly Media.