[БЕЗ ЗВУКА]
[БЕЗ ЗВУКА] Всем привет!
В этом видео мы начнем рассматривать новую большую тему про хранение данных.
Мы обсудим, какие данные мы будем хранить, где их лучше хранить,
в чем преимущества и недостатки разных вариантов хранения данных.
Зачем нам вообще нужно хранить данные локально?
Ведь мы только что получали их по API, мы можем получить их и еще раз.
Может быть, тогда нам вообще и не надо их сохранять?
Да, мы можем получить данные еще раз, но можем и не получить.
Сайт, который работал минуту назад, может оказаться недоступным.
У API, которым мы пользуемся, могут быть какие-то ограничения по числу,
по частоте его использования.
Данные могут устареть на сайте, а мы хотим хранить историю.
Ну, например, сайт дает нам курс валют только на сегодня,
а мы хотим знать и на вчера, и на позавчера.
Если мы каждый день забираем их, мы можем сохранять всю эту историю.
К тому же, сайт скорее всего, не стоит на соседнем сервере,
а находится где-то далеко, и обращаться к нему по сети довольно-таки долго.
Если пользователь запрашивает нас, а мы запрашиваем сторонний сайт,
то пользователь все это время ждет.
Гораздо лучше, если бы нужные ему данные лежали у нас где-то рядом,
чтобы мы их сразу отдали.
К тому же, данные могут быть предоставлены самим пользователем.
Тогда уж нам их точно придется сохранить.
Больше нам их получить неоткуда.
Второй раз пользователь вряд ли захочет вводить то же самое.
Так что, данные нам в любом случае придется хранить.
Ну, и плюс локальное хранение данных — это нужно для удобства манипуляции с ними,
поиска и так далее.
Вообще, существует два основных варианта хранения
данных — это кэширование и какое-то долгосрочное хранение.
Кэширование подразумевает, что мы берем какие-то очень часто используемые данные и
кладем их в этот кэш, но данные в кэше могут потеряться.
Для нас это не будет страшно, потому что мы их опять сможем взять оттуда,
откуда мы их брали и снова положить в этот же самый кэш.
То есть мы какие-то долго получаемые данные можем сложить в кэш и быстро их
оттуда отдавать, но, если в какой-то момент этих данных в кэше не окажется по
какой-то причине, ничего страшного, мы можем их заново получить.
Просто главное, чтобы слишком часто не случалось.
А долгосрочное хранение, оно подразумевает,
что данные у нас действительно хранятся и никуда не теряются.
Давайте подумаем.
Данные ведь у нас уже хранятся на самом деле.
Если мы их откуда-то получили и сложили в Python в какой-то массив или словарь,
они уже там хранятся.
В общем-то, хранятся в памяти программы.
Если данных мало, а памяти много, а программа у нас никогда не завершается,
почему бы их не хранить там?
Действительно, можно.
Но надо понимать, что это ровно до того момента,
когда программа прекратит работать.
Это может случиться из-за того, что сервер перегрузился,
из-за того, что в программе возникла ошибка.
Да мало ли почему.
Соответственно, наверно, вот кэшировать какие-то небольшие порции данных именно
в памяти программы вполне себе можно.
Для этого нам ничего не нужно.
Да, мы их получили, можем отдавать сколько угодно раз из того же словаря либо списка,
который у нас есть.
Это просто очень большая скорость отдачи, потому что они в памяти лежат.
Можно хранить очень сложные структуры, и, главное,
ничего для этого не предпринимать.
Но это не надежно.
Памяти может не хватить.
Если вы попробуете создать очень-очень большой массив,
то это может закончиться тем, что система просто убьет ваше приложение из-за того,
что оно сожрало слишком много памяти.
Память, вообще, дорогая.
А что у нас будет с масштабированием?
Да ничего.
Если у вас ваше приложение запущено на двух компьютерах, у каждого — своя память,
и общих данных у них нет.
Да даже в двух разных процессах и то будут сложности с обменом данных.
К тому же, данные могут устаревать,
и вам придется реализовать какой-то механизм, чтобы те данные,
которые вот вы храните у себя, были обновлены, когда придет время, потому
что вы же будете все время отдавать одни и те же, если просто все делать в лоб.
Давайте подумаем, как же еще.
Если мы хотим хранить в памяти, но не в программе, существует уже готовое решение.
Напрмер, Memcache, Redis или Tarantool.
Это сервера.
Они устанавливаются отдельно, и они умеют хранить данные в памяти.
Redis и Tarantool помимо этого еще могут записывать данные на диск.
То есть несмотря на то, что он хранит их в памяти, он их попутно пишет на диск так,
чтобы в случае какого-то сбоя он их мог оттуда восстановить.
Memcache в этом случае, если будет такой сбой, данные потеряет.
Но он, собственно говоря, в названии даже кэш.
Кэш подразумевает, что данные могут потеряться,
зато он очень быстрый Redis мощнее, чем Memcache.
В нем есть не только возможность, хранить данные по ключу, какие-то значения,
но и могут быть различные типы данных, которые он по ключу может сохранить,
словари тоже, списки.
Поддерживает различные операции над данными.
Tarantool еще больше возможностей предоставляет.
Ну, в первую очередь,
такие вот системы используются для хранения пар ключ-значений.
Например, вот как словарь в Python, только в стороннем сервисе.
Через какое-то API вы обращаетесь к нему, сохраняете свои данные,
потом можете их получить.
Также они поддерживают как раз механизм устаревания.
То есть вы можете сказать,
что данные по этому ключу должны быть годными в течение какого-то времени.
Если вы их попробуете получить после этого,
то вам эти данные не будут возвращены.
Все, как будто бы их и не было.
Это иногда бывает очень удобно.
А, может, хранить их бесконечно долго, по крайней мере, в Redis c Tarantool.
Все эти системы очень быстрые, и у них есть модули для Python.
То есть с ними со всеми достаточно удобно работать из Python.
Из минусов, что памяти никогда не бывает слишком много.
То есть память всегда ограничена, а данных-то бывает много.
Ну, и все-таки это сторонний сервис, вам придется их устанавливать,
настраивать и так далее.
Также, когда мы говорим о хранении данных, приходит в голову мысль о том,
почему бы их не писать в файлы.
Логично.
Особенно, если речь идет о каких-нибудь картинках пользователя и других данных,
почему бы нет?
Но, если речь идет о каких-то сложных данных, то, может быть, все не так просто.
Ну, с другой стороны, если мы получили данные из какого-то API, то нам пришла
строка, либо это JSON, либо XML, как правило, мы можем ее сохранить в файл.
Это будет очень удобно.
И потом, в следующий раз, когда нам нужны будут те же самые данные,
мы не пойдем по сети, а прямо возьмем сразу их из файла.
Точно так же распарсим, и вот оно удобно.
А что будет, если во время того, как мы записываем данные, например, моргнет свет?
Данные у нас могут записаться не полностью, или,
если мы перетираем одни данные другими, то будет еще хуже.
Часть данных там сверху запишет, а часть не запишется.
Может быть неконсистентность данных или вообще их потеря.
А что будет, например, если у нас несколько процессов одновременно
обращаются к одному и тому же файлу?
Например, у нас в файле есть какой-то счетчик, записана циферка, мы ее читаем,
увеличиваем на единичку и записываем обратно.
Если два процесса одновременно прочтут эту единичку, одновременно увеличенную
еще на единичку, и одновременно запишут эту двойку, то мы получим там два.
А хотелось бы получить, например, три.
Ну, то есть чтобы первый прочел, увеличил, второй прочел, увеличил.
Но, если они будут запущены последовательно,
мы получим один результат, если одновременно — то другой.
Все это не очень хорошо.
Что у нас с масштабированием?
Тоже все плохо.
Если у вас несколько серверов, то на каждом — своя файловая система.
Есть, конечно, сетевые распределенные файловые системы,
но это уже отдельная песня.
А что если у нас данных очень много?
Вот мы их записываем, записываем, записываем в файл.
Например, там все население России, а нам нужен какой-то один человек.
Ну что, мы будем последовательно читать весь этот файл и искать в нем нужные
данные?
Это будет долго.
Если мы прочтем все это в память, памяти может не хватить.
И опять как бы это все не очень хорошо получается.
Ну, и решением в нашем случае будет использовать базу данных.
База данных, или правильнее система управления базами данных,
обеспечивает как раз работу с большими объемами данных.
Она обеспечивает управление данными на диске или в памяти,
целостность этих данных, резервирование данных, и, как правило,
у нее есть какой-то язык для доступа и определения этих данных.
Все достаточно удобно.
Типов баз данных бывает очень много, по разным параметрам.
Например, бывают клиент-серверные или встроенные базы данных.
Клиент-серверные подразумевают, что у баз данных есть отдельно выделенный сервер,
а ваше приложение является клиентом, оно обращается к серверу,
сохраняет там данные, получает по какому-то протоколу.
А встроенные подразумевают,
что нет никакого выделенного сервера баз данных, система управления базы данных
встраивается прямо в непосредственно ваше приложение и поставляется вместе с ним.
Не требует никакой установки и работает прямо вместе с вашим приложением.
Также есть, например, локальные и распределенные базы данных.
Локальные базы данных — это когда все файлы, все таблицы, все-все,
что есть в этой базе данных, хранится на одном компьютере.
А распределенные — это когда база данных работает на нескольких серверах
одновременно.
Бывают также реляционные и нереляционные базы данных.
Реляционные базы данных — это которые состоят из таблиц и отношений между ними,
а нереляционные — это, как правило, хранилище «ключ-значение»,
там нет связей между таблицами никаких.
Это вот как раз Redis, Tarantool.
Это нереляционная база данных.
Базы данных могут хранить огромное количество записей, как правило,
то есть миллиарды совершенно свободно,
очень быстро выбирать из этих записей нужные по каким-то параметрам,
не перебирая все записи полностью, разрешают как раз коллизии, когда там,
например, два процесса одновременно обновляют какую-то одну и ту же запись,
могут работать по сети, то есть с другого компьютера иметь доступ,
могут организовываться в кластера, тем самым решая проблему как
раз масштабирования и так далее, и многое другое.
Таким образом, в этом занятии мы узнали, что данные надо хранить и кэшировать.
Кэш используется для быстрых, горячих данных,
которые нам не очень жалко потерять.
То есть мы их можем быстро отдать, мы можем их потерять,
и если что мы можем их восстановить.
Пусть это займет у нас чуть больше времени.
А СУБД используется для надежного хранения данных в течение длительного времени.
Как правило, они тоже достаточно быстрые, но кэш быстрее.
Они надежно хранят и изменяют данные.
Существует очень много разных типов систем управления баз данных.
Бывают реляционные, нереляционные.
Со всеми из них достаточно легко работать из Python.
И в следующем видео мы более подробно начнем разбирать реляционные базы данных.
[ЗВУК] [БЕЗ ЗВУКА]