Тиринг данных в объектном хранилище

В этой инструкции описано, как настроить тиринг данных вверх — автоматическое перемещение данных в более «горячий» класс хранения при запросе к архивным объектам.

О тиринге данных

Объектное хранилище Object Storage Service (OBS) поддерживает три класса хранения в зависимости от частоты обращения к данным:

  • Standard — стандартный или «горячий» с высоким уровнем доступа к постоянно используемым объектам.

  • Warm — редкий или «теплый» для информации, доступ к которой требуется несколько раз в год.

  • Cold — архивный или «холодный» для редко используемых объектов с частотой обращения на уровне одного раза в год или реже.

Чтобы уменьшить затраты на хранение, вы можете использовать правила управления жизненным циклом. Эти правила позволяют реализовать тиринг данных вниз — автоматически перемещать в класс с редким доступом (Warm) или на архивное хранение (Cold) данные, к которым больше не нужен частый доступ.

В некоторых сценариях архивные данные (с классом хранения Cold) могут стать востребованными. Например, может вырасти спрос на видеозапись, песню или книгу из электронной библиотеки. Объекты с классом хранения Cold нельзя получить с помощью GET-запроса. Чтобы сделать их снова доступными, их восстанавливают в более «горячий» класс хранения — Standard или Warm.

Ниже описано, как реализовать перемещение (восстановление) объекта из класса хранения Cold в более «горячий» класс хранения — Warm или Standard. Перемещение будет автоматически запускаться при обращении к объекту с помощью GET-запроса. Повторное обращение к нему позволяет получить сам объект после его восстановления.

Архитектура решения

../_images/schm__data-tiering-algorithm.svg
  1. Клиент (пользователь или приложение) отправляет GET-запрос к объекту с классом хранения Cold или Warm.

  2. Информация об обращении к целевому бакету попадает в Cloud Trace Sevice — сервис для логирования событий.

  3. Cloud Trace Service формирует лог и отправляет его в бакет для хранения логов.

  4. OBS сообщает сервису для отправки уведомлений Simple Message Notification о появившемся файле с логами в бакете.

  5. Уведомление из Simple Message Notification становится триггером для запуска функции в FunctionGraph — сервисе для выполнения кода в бессерверной среде по триггеру.

  6. Функция в FunctionGraph отрабатывает и перемещает объект в целевом бакете в класс хранения Standard.

Подготовьте бакет для хранения логов в OBS

  1. На панели управления в разделе Storage откройте Object Storage Service.

  2. Перейдите к созданию бакета — нажмите Create Bucket.

  3. В поле Bucket Name введите название, например «logs-for-tiering».

  4. В поле Storage Class выберите для хранения логов класс Warm.

  5. Выберите проект в поле Enterprise Project. Проекты помогают управлять доступом к облачным ресурсам. Хорошая практика — создать новый проект и поместить бакет в него, а не использовать проект по умолчанию «default».

  6. Подтвердите создание — нажмите Create Now.

Создайте трекер в CTS

  1. На панели управления в разделе Management & Deployment откройте Cloud Trace Service (CTS).

  2. Убедитесь, что в качестве IAM-проекта на верхней панели выбран проект по умолчанию — «ru-moscow».

  3. На вкладке Trackers перейдите к созданию трекера — нажмите Create Tracker.

  4. Задайте параметры трекера:

    • Tracker Type — укажите тип Data.

    • Tracker Name — введите название, например «obs-logs».

    • OBS Bucket — выберите бакет с объектами, для которых вы настраиваете тиринг данных. CTS будет фиксировать обращения к объектам этого бакета и отправлять логи о таких событиях.

    • В блоке Transfer to OBS в поле OBS Bucket выберите созданный ранее бакет для хранения логов.

    • В поле Retention Period задайте время хранения логов в бакете, например 60 дней.

  5. Сохраните трекер — нажмите OK.

Настройте топик в SMN

Топик — это инструмент, объединяющий уведомление об указанном событии, получателя (подписчика) и отправителя этого уведомления. Как только наступает событие, отправитель публикует уведомление, и его получают все подписчики.

  1. На панели управления в разделе Application откройте Simple Message Notification (SMN).

  2. В разделе Topic Management → Topics перейдите к созданию топика — нажмите Create Topic.

  3. Задайте параметры топика:

    • Topic Name — введите название топика, например «bucket-request».

    • Enterprise Project — выберите созданный ранее проект.

  4. Сохраните топик — нажмите OK.

  5. В строке с созданным топиком нажмите More → Configure Topic Policy, чтобы задать политику работы топика.

  6. В списке Services that can publish messages to this topic отметьте сервис OBS и сохраните политику кнопкой OK.

Настройте уведомление о создании файла в бакете

  1. На панели управления в разделе Storage откройте Object Storage Service.

  2. Выберите созданный для хранения логов бакет.

  3. Нажмите Event Notification → Create, чтобы добавить уведомление.

  4. Задайте параметры уведомления:

    • Name — введите название, например «event-create-file».

    • Events — выберите тип события ObjectCreated.

    • В выпадающем списке Select the project to which the SMN topic belongs выберите IAM-проект, в котором создан топик.

    • В выпадающем списке Select an SML topic выберите созданный ранее топик.

  5. Сохраните уведомление — нажмите OK.

Создайте агентство для FunctionGraph в IAM

  1. На панели управления в разделе Management & Deployment откройте Identity and Access Management (IAM).

  2. На странице Agencies перейдите к созданию агентства — нажмите Create Agency.

  3. Задайте параметры агентства:

    • Agency Name — введите название агентства, например «for-functiongraph».

    • Agency Type — задайте тип Cloud Service.

    • Cloud Service — выберите FunctionGraph.

    • Validity Period — выберите Unlimited.

    • Нажмите Assign Permissions и выберите политики OBS Administrator и SMN Administrator.

  4. Сохраните агентство — нажмите OK.

Создайте функцию в FunctionGraph

  1. На панели управления в разделе Computing откройте FunctionGraph.

  2. На странице Functions → Function List перейдите к созданию функции — нажмите Create Function.

  3. Задайте параметры функции:

    • Function Name — введите название, например «data-tiering».

    • Agency — выберите созданное на предыдущем шаге агентство.

    • Enterprise Project — выберите созданный ранее проект.

      Примечание

      Функция должна принадлежать тому же проекту, что и топик SMN.

    • Runtime — укажите среду выполнения кода. В нашем примере код написан на Python 3.6

    • В редактор вставьте код функции.

      Пример реализации функции тиринга на Python 3.6

      import os
      
      from com.obs.client.obs_client import ObsClient
      from obs import PutObjectHeader
      from obs import RestoreTier
      import time
      
      import json
      import gzip
      
      def handler (event, context):
          # Obtain and print an event
          print("event:" + json.dumps(event) )
      
          # Obtain and print the content of an SMN message
          message = event['record'][0]['smn']['message']
          print("message:" + message)
      
          # Parse content of an SMN message (JSON string) and convert it into a Python Dictionary
          data = json.loads(message)
      
          # Obtain and print name of bucket with trace files (according to tracking bucket, from CTS service) from the content of an SMN message
          bucket_name_tracker = data['Records'][0]['s3']['bucket']['name']
          print("bucket_name_tracker:" + bucket_name_tracker)
      
          # Obtain and print name of created .json.gz trace file with operation logs (according to tracking bucket, from CTS service) from the content of an SMN message
          object_key_tracker = data['Records'][0]['s3']['object']['key']
          print("object_key_tracker:" + object_key_tracker)
      
          # Obtain an Access Key
          ak = context.getAccessKey()
          # Obtain an Secret Key
          sk = context.getSecretKey()
      
          # Set up endpoint for OBS
          endpoint = "obs.ru-moscow-1.hc.sbercloud.ru"
      
          # Open connection to OBS
          conn = ObsClient(access_key_id=ak, secret_access_key=sk, server=endpoint, path_style=True, region="ru-moscow-1")
      
          # Construct the local path of the incoming file
          local_incoming_file_name = os.path.join(os.sep, "tmp", object_key_tracker)
      
          # Download the trace file with operation logs (according to tracking bucket, from CTS service) from the bucket with trace files
          resp = conn.getObject(bucket_name_tracker, object_key_tracker, local_incoming_file_name)
      
          # Decompress .json.gz trace file, read, parse, convert it into a Python Dictionary and print the operation logs from it
          with gzip.open(local_incoming_file_name, "rb") as f:
            logs_data = json.loads(f.read())
          print(json.dumps(logs_data))
          print (len(logs_data))
      
          # Obtain operation logs details for traces with GET.OBJECT tracker name (to make following operations ONLY for objects to which GET request were made)
          for i in logs_data:
              if "GET.OBJECT" in i['trace_name']:
                  resource_name = i['resource_name']
                  print("resource_name:" + resource_name)
                  # Obtain and print name of bucket with objects (tracking bucket) from operation logs details
                  backet_name_logs = resource_name.split(':')[0]
                  print("backet_name_logs:" + backet_name_logs)
                  # Obtain and print object name with objects (tracking bucket) from operation logs details
                  object_key_logs = resource_name.split(':')[1]
                  print("object_key_logs:" + object_key_logs)
      
                  # Obtain and print storage class of the object (Standard storage class value is None, Warm storage class value is STANDARD_IA, Cold storage class value is GLACIER)
                  resp = conn.getObjectMetadata(bucketName = backet_name_logs, objectKey = object_key_logs)
                  object_storageClass = resp.body.storageClass
                  print(object_storageClass)
      
                  # Change storage class to STANDARD if storage class of the tracking object is WARM (value is STANDARD_IA)
                  if object_storageClass == 'STANDARD_IA':
                      headers = PutObjectHeader()
                      headers.storageClass = 'STANDARD'
                      # Change storage class in object header to STANDARD and print the message after this operation is completed
                      resp = conn.putContent(bucketName = backet_name_logs, objectKey = object_key_logs, headers = headers)
                      print("object " + object_key_logs + " has STANDARD storage class now!")
      
                  # Change storage class to STANDARD if storage class of the tracking object is COLD (value is GLACIER)
                  if object_storageClass == 'GLACIER':
                      # Obtain and print restore status of the tracking object (Unrestored (when object is in archive and can not be downloaded) or Restored). If the tracking object is Unrestored, the value is None.
                      object_restore = resp.body.restore
                      print(object_restore)
      
                      # If the tracking object is Unrestored (in archive)
                      if object_restore is None:
                          # Restore the tracking object with the fastest restoration option - Expedited. Expedited restoration restores an object in 1 to 5 minutes.
                          resp = conn.restoreObject(bucketName = backet_name_logs, objectKey = object_key_logs, days = 1, tier = RestoreTier.EXPEDITED)
                          # Wait for 6 minutes
                          time.sleep(6 * 60)
                          headers = PutObjectHeader()
                          headers.storageClass = 'STANDARD'
                          # Change storage class in object header to STANDARD and print the message after this operation is completed
                          resp = conn.putContent(bucketName = backet_name_logs, objectKey = object_key_logs, headers = headers)
                          print("object " + object_key_logs + " has STANDARD storage class now!")
      
                      # If the tracking object is Restored
                      else:
                          headers = PutObjectHeader()
                          headers.storageClass = 'STANDARD'
                          # Change storage class in object header to STANDARD and print the message after this operation is completed
                          resp = conn.putContent(bucketName = backet_name_logs, objectKey = object_key_logs, headers = headers)
                          print("object " + object_key_logs + " has STANDARD storage class now!")
      
                  # If storage class of the tracking object is already STANDARD (value is None) print the message about it
                  if object_storageClass is None:
                      print("object " + object_key_logs + " already has STANDARD storage class")
      
          return "ok"
      
  4. Сохраните функцию — нажмите Create Now.

  5. На вкладке Code в поле Dependencies нажмите Select, чтобы прикрепить зависимость.

  6. Выберите obssdk-3.0.2 для Python и нажмите OK. Этот SDK поддерживает Python версии 2.7.8 и позднее, а также Python 3.3–3.6.

  7. На вкладке Configuration убедитесь, что в поле Agency выбрано нужное агентство.

  8. В поле Execution Timeout (s) укажите время таймаута в секундах. С учетом восстановления из класса хранения Cold необходимо задать не менее 370 секунд.

  9. На вкладке Triggers нажмите Create Trigger, чтобы создать триггер.

  10. Задайте параметры триггера:

    • Trigger Type — выберите тип Simple Message Notification (SMN).

    • Topic Name — выберите созданный ранее топик.

  11. Сохраните триггер — нажмите OK.

Теперь при GET-запросе к объектам бакета класс хранения объектов будет автоматически изменяться на Standard («горячие данные»), а при повторном обращении после восстановления можно будет получить сам объект.

Примечание

В функции используется опция Expedited, которая позволяет восстановить объект в течение 1–5 минут.

Запустили Evolution free tier
для Dev & Test
Получить