Сообщения

Сообщения за 2020

Реализация ACID в базах данных

Изображение
Обработка транзакции часто требует последовательности операций, которая может выйти из строя по ряду причин. Например, в системе может не осталось места на дисках или она израсходовала выделенное время ЦП. Существует два популярных семейства методов: ведение журнала с упреждающей записью и теневая подкачка. В обоих случаях необходимо установить блокировки для всей обновляемой информации и, в зависимости от уровня изоляции, возможно, для всех данных, которые также могут быть прочитаны. При ведении журнала с упреждающей записью надежность гарантируется путем копирования исходных (неизмененных) данных в журнал перед изменением базы данных. Это позволяет базе данных вернуться в согласованное состояние в случае сбоя. При теневом копировании обновления применяются к частичной копии базы данных, и новая копия активируется при фиксации транзакции. Блокировка и многоверсионность Многие базы данных полагаются на блокировку для обеспечения возможностей ACID. Блокировка означает, что транзакция

Примеры ACID в базах данных

Изображение
Следующие ниже примеры дополнительно иллюстрируют свойства ACID. В этих примерах таблица базы данных имеет два столбца, A и B. Ограничение целостности требует, чтобы сумма значения в A и значения в B равнялась 100. Следующий код SQL создает таблицу, как описано выше: CREATE TABLE acidtest (A INTEGER, B INTEGER, CHECK (A + B = 100)); Атомарность Атомарность - это гарантия того, что серия операций с базой данных в атомарной транзакции либо будет выполнена (успешная операция), либо ничего не произойдет (неудачная операция). Серии операций нельзя разделить, выполняя только некоторые из них, что делает серию операций "неделимой". Гарантия атомарности предотвращает частичное обновление базы данных, что может вызвать более серьезные проблемы, чем полный отказ от всей серии. Другими словами, атомарность означает неделимость и несводимость. В качестве альтернативы мы можем сказать, что логическая транзакция может состоять из одной или нескольких физических транзакций или сост

ACID в базах данных

Изображение
В информатике ACID (atomicity, consistency, isolation, durability - атомарность, согласованность, изоляция, долговечность) - это набор свойств транзакций базы данных, предназначенный для гарантии достоверности данных, несмотря на ошибки, сбои питания и другие неполадки. В контексте баз данных последовательность операций с базой данных, удовлетворяющая свойствам ACID (которые могут восприниматься как единственная логическая операция над данными), называется транзакцией. Например, перевод средств с одного банковского счета на другой, даже если он включает в себя несколько изменений, таких как дебетование одного счета и зачисление другого, является одной транзакцией. В 1983 году Андреас Рейтер и Тео Хердер придумали аббревиатуру ACID, основываясь на более ранней работе Джима Грея, который при характеристике концепции транзакции назвал атомарность, согласованность и долговечность, но не изоляцию. Эти четыре свойства являются основными гарантиями парадигмы транзакций, которая повлияла на

PostgreSQL: индексы

Изображение
Предположим, у нас есть таблица, подобная этой: CREATE TABLE table1 ( id integer, content varchar ); и приложение выдает множество запросов в форме: SELECT content FROM table1 WHERE id = constant; Без предварительной подготовки системе придется сканировать всю таблицу table1, строка за строкой, чтобы найти все совпадающие записи. Если в table1 много строк и только несколько строк (возможно, ноль или одна), которые могут быть возвращены таким запросом, это явно неэффективный метод. Но если система получила указание поддерживать индекс в столбце id, она может использовать более эффективный метод поиска совпадающих строк. Например, ему может потребоваться пройти всего несколько уровней в глубину дерева поиска. Аналогичный подход используется в большинстве научно-популярных книг: термины и концепции, которые часто ищут читатели, собраны в алфавитном указателе в конце книги. Заинтересованный читатель может относительно быстро просмотреть указатель и перейти к соответс

Уровни изоляции в базах данных

Изображение
Из четырех свойств ACID в СУБД (система управления базами данных) свойство изоляции наиболее часто ослабляется. Пытаясь поддерживать наивысший уровень изоляции, СУБД обычно устанавливает блокировки данных, что может привести к потере конкурентности, или реализует контроль одновременного выполнения нескольких версий. Это требует добавления логики для правильной работы приложения. Большинство СУБД предлагают несколько уровней изоляции транзакций, которые контролируют степень блокировки, возникающей при выборе данных. Для многих приложений баз данных большинство транзакций базы данных может быть построено так, чтобы не требовать высоких уровней изоляции (например, уровень SERIALIZABLE), тем самым снижая накладные расходы на блокировку для системы. Программист должен тщательно проанализировать код доступа к базе данных, чтобы гарантировать, что любое ослабление изоляции не вызовет программных ошибок, которые трудно найти. И наоборот, если используются более высокие уровни изоляции, вероят

Изоляция в базах данных

Изображение
В системах баз данных изоляция определяет, как целостность транзакции видна другим пользователям и системам. Например, когда пользователь создает заказ на покупку и создал заголовок, но не строки заказа на покупку, доступен ли заголовок для просмотра другим системам или пользователям (выполняющим параллельные операции, например, отчет по заказам на покупку)? Более низкий уровень изоляции увеличивает возможность доступа многих пользователей к одним и тем же данным в одно и то же время, но увеличивает количество эффектов параллелизма (таких как грязное чтение (dirty reads) или потерянные обновления (lost updates)), с которыми могут столкнуться пользователи. И наоборот, более высокий уровень изоляции уменьшает типы эффектов параллелизма, с которыми могут столкнуться пользователи, но требует больше системных ресурсов и увеличивает вероятность того, что одна транзакция заблокирует другую. Изоляция обычно определяется на уровне базы данных как свойство, которое определяет, как и когда изме

Kotlin, базовый синтаксис: строковые шаблоны, условные выражения

Изображение
Строковые шаблоны var a = 1 // простое имя в шаблоне: val s1 = "a is $a" a = 2 // произвольное выражение в шаблоне: val s2 = "${s1.replace("is", "was")}, but now is $a" Условные выражения fun maxOf(a: Int, b: Int): Int { if (a > b) { return a } else { return b } } В Kotlin, if также можно использовать в качестве выражения: fun maxOf(a: Int, b: Int) = if (a > b) a else b Читайте также: Kotlin, базовый синтаксис: пакет, импорт, входная точка, функции Kotlin, базовый синтаксис: переменные Kotlin, базовый синтаксис: комментарии

Не устанавливайте Postgres. Docker pull Postgres

Изображение
С момента появления Docker нет необходимости непосредственно устанавливать программное обеспечение для разработки на локальном компьютере. Будь то серверы баз данных (например, Postgres), системы кеширования (например, Redis, Memcache) или системы обмена сообщениями (например, Kafka) - почти всегда можно найти или создать подходящий docker образ для использования во время разработки. Установить программное обеспечение сложно. И это не имеет ничего общего с вашим опытом в качестве разработчика. Все видели значительную долю столкновений версий, эзотерических сообщений об ошибках сборки и отсутствующих ошибок зависимостей каждый раз, когда приступали к задаче установки нового программного обеспечения для использования. Тратили бесчисленное количество часов, копируя фрагменты кода из Stack Overflow в терминал и выполняли их, надеясь, что один из них волшебным образом решит проблемы установки и заставит программное обеспечение работать. Результатом являются в основном отчаяние, разочарован

Kotlin, базовый синтаксис: комментарии

Изображение
Как и большинство современных языков, Kotlin поддерживает однострочные (или конец строки) и многострочные (блочные) комментарии. // Однострочный комментарий ​/* Блочный комментарий на несколько строк. */ Блок комментариев в Kotlin может быть вложенным. /* Комментрий начинается здесь /* содержит вложенный комментарий */ и заканчивается здесь. */ Читайте также: Kotlin, базовый синтаксис: пакет, импорт, входная точка, функции Kotlin, базовый синтаксис: переменные

Простое приложение с Docker: запуск сервиса, масштабирование приложения

Изображение
Запуск приложения с балансировкой нагрузки Прежде чем мы сможем использовать команду docker stack deploy, мы сначала запустим: docker swarm init Примечание. Описание docker swarm будет в последующих постах. Если вы не запустите docker swarm init, вы получите сообщение об ошибке “this node is not a swarm manager”. Теперь давайте запустим это. Вы должны дать своему приложению имя. Здесь установлено значение getstartedlab: docker stack deploy -c docker-compose.yml getstartedlab В нашем единственном стеке службы запущено 5 экземпляров нашего развернутого образа на одном хосте. Рассмотрим их подробней. Получите идентификатор службы (service ID) для одной службы в нашем приложении: docker service ls Ищите выходные данные для web службы, с добавлением имени вашего приложения. Если вы назвали его так же, как показано в этом примере, это имя getstartedlab_web. Также указывается идентификатор службы, а также количество реплик, имя образа и открытые порты. В качестве альт

Простое приложение с Docker: сервисы и файл docker-compose.yml

Изображение
В этом посте мы масштабируем наше приложение, созданное в предыдущих постах , и включим балансировку нагрузки. Чтобы сделать это, мы должны перейти на один уровень вверх в иерархии распределенного приложения: службы (services). Stack Services (в этом посте) Container (в посте ) О сервисах В распределенном приложении разные части приложения называются " сервисами " (службы). Например, если вы представляете сайт для обмена видео, он, вероятно, включает в себя сервис для хранения данных приложения в базе данных, сервис для транскодирования видео в фоновом режиме после того, как пользователь что-то загрузил, сервис для внешнего интерфейса и так далее. Сервисы на самом деле являются просто "контейнерами в производстве" (containers in production). Сервис запускает только образ, но он кодифицирует способ работы образа: какие порты он должен использовать, сколько реплик (экземпляров) контейнера должно работать, чтобы у службы была необходимая емкость, и т.д. Масшта

Простое приложение с Docker: публикация образа

Изображение
Чтобы продемонстрировать переносимость приложения в контейнере, которое мы создали в предыдущих постах , давайте загрузим наш собранный образ и запустим его где-нибудь еще. В конце концов, чтобы развертывать контейнеры в производственной среде, необходимо уметь передавать образы в реестры. Реестр (registry) - это набор репозиториев, а репозиторий - это набор образов, вроде репозитория GitHub, за исключением того, что код уже собран (пройден build этап). Учетная запись в реестре может создавать множество репозиториев. Интерфейс командной строки docker по умолчанию использует общедоступный реестр Docker. Примечание. Здесь мы используем общедоступный реестр Docker только потому, что он бесплатный и предварительно настроен, но есть из чего выбирать, и вы даже можете создать свой личный реестр с помощью Docker Trusted Registry. Войдите с вашим Docker ID Если у вас нет учетной записи Docker, зарегистрируйтесь на hub.docker.com . Запишите ваше имя пользователя. Войдите в публичный реест

Простое приложение с Docker: сборка и запуск приложения в контейнере

Изображение
Сборка приложения Мы готовы собрать приложение, которое мы создали в предыдущем посте . Убедитесь, что вы все еще на верхнем уровне вашего нового каталога. Вот что должен показать ls: $ ls Dockerfile app.py requirements.txt Теперь запустите команду сборки (build command). Она создает образ Docker, который мы назовем с помощью параметра --tag. Используйте -t, если вы хотите использовать более короткий вариант. docker build --tag=friendlyhello . Где ваш встроенный образ? Он находится в локальном реестре образов Docker вашей машины: $ docker image ls REPOSITORY TAG IMAGE ID friendlyhello latest 326387cea398 Обратите внимание, что тег по умолчанию latest (последний). Полный синтаксис для опции тега будет --tag=friendlyhello:v0.0.1. Устранение неполадок для пользователей Linux Настройки прокси-сервера Прокси-серверы могут блокировать подключения к вашему веб-приложению после его установки и запуска. Если вы находитесь

Простое приложение с Docker: определение контейнера с помощью Dockerfile

Изображение
Пришло время приступить к созданию приложения в стиле Docker. Мы начинаем с нижней части иерархии такого приложения, контейнера (container), который описывает этот пост. Над этим уровнем находится служба (service), которая определяет поведение контейнеров в процессе эксплуатации. Наконец, на верхнем уровне находится стек (stack), определяющий взаимодействия всех служб. Stack Services Container Ваша новая среда разработки Раньше, если бы вы начали писать приложение на Python, первым делом вам нужно было установить среду исполнения Python на ваш компьютер. Но это создает ситуацию, когда среда на вашем компьютере должна быть идеальной для того, чтобы ваше приложение работало должным образом, а также должна соответствовать вашей производственной среде. С помощью Docker вы можете просто взять переносимую среду выполнения Python как образ, без необходимости установки. Затем ваша сборка может включать в себя базовый образ Python вместе с кодом приложения, обеспечивая совместное перем

Подготовка вашего Docker окружения

Изображение
Установите поддерживаемую версию Docker Community Edition (CE) или Enterprise Edition (EE) на поддерживаемой платформе . Установка Docker CE на Ubuntu: # Установка использования Docker репозитория sudo apt-get update sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" # Установка Docker CE sudo apt-get update sudo apt-get install docker-ce # Добавление своего пользователя в docker group sudo usermod -aG docker $USER # Установка docker/compose sudo apt-get install python3-pip sudo pip3 install --upgrade pip3 sudo pip3 install docker-compose Тестирование версии Docker Запустите docker --version и убедитесь, что у вас есть поддерживаемая версия Docker: docker --version Docker version 17.12.0-ce, build c9

Kotlin, базовый синтаксис: переменные

Изображение
Локальные переменные только для чтения определяются с помощью ключевого слова val. Им может быть присвоено значение только один раз. val a: Int = 1 // немедленное назначение val b = 2 // `Int` тип выведен val c: Int // Тип требуется, // когда инициализатор не предоставлен c = 3 // отложенное присваивание Переменные, которые можно переназначить, используют ключевое слово var: var x = 5 // `Int` тип выведен x += 1 Переменные верхнего уровня: val PI = 3.14 var x = 0 fun incrementX() { x += 1 } Читайте также: Kotlin, базовый синтаксис: пакет, импорт, входная точка, функции

Kotlin, базовый синтаксис: пакет, импорт, входная точка, функции

Изображение
Определение пакета и импорты Спецификация пакета должна быть вверху исходного файла: package my.demo import kotlin.text.* // ... Совпадение каталогов и пакетов не требуется: исходные файлы могут быть произвольно размещены в файловой системе. Точка входа в программу Точкой входа в Kotlin приложение является main функция. fun main() { println("Hello world!") } Функции Функция, имеющая два параметра Int с типом возврата Int: fun sum(a: Int, b: Int): Int { return a + b } Функция с телом выражения и предполагаемым типом возврата: fun sum(a: Int, b: Int) = a + b Функция не возвращает никакого значимого значения: fun printSum(a: Int, b: Int): Unit { println("sum of $a and $b is ${a + b}") } Тип возврата Unit может быть опущен: fun printSum(a: Int, b: Int) { println("sum of $a and $b is ${a + b}") }

Концепции Docker

Изображение
Docker - это платформа для разработчиков и системных администраторов для разработки, развертывания и запуска приложений с контейнерами. Использование контейнеров Linux для развертывания приложений называется контейнеризацией. Контейнеры не новы, но новое здесь - это их использование для легкого развертывания приложений. Контейнеризация становится все более популярной, потому что контейнеры: Гибкие : даже самые сложные приложения могут быть упакованы в контейнеры. Легкие : контейнеры используют и разделяют ядро хоста. Взаимозаменяемые : вы можете развертывать обновления и выполнять обновления на лету. Переносимые : вы можете создавать локально, развертывать в облаке и работать где угодно. Масштабируемые : Вы можете увеличивать и автоматически распределять реплики контейнера. Складываемые в стеки : вы можете размещать сервисы вертикально и на лету. Образы и контейнеры Контейнер запускается путем запуска образа (image). Образ - это исполняемый пакет, который включает в себя в

Паттерн фасад

Изображение
Паттерн фасад (также пишется как façade) - это паттерн программного проектирования, обычно используемый в объектно-ориентированном программировании. Аналогично фасаду в архитектуре, фасад - это объект, который служит интерфейсом на передней панели, маскируя более сложный базовый или структурный код. Фасад может: улучшить удобочитаемость и удобство использования библиотеки программного обеспечения, маскируя взаимодействие с более сложными компонентами за одним (и часто упрощенным) API обеспечить контекстно-специфический интерфейс для более общей функциональности (в комплекте с контекстно-зависимой проверкой входных данных) служить отправной точкой для более широкого рефакторинга монолитных или тесно связанных систем в пользу более слабосвязанного кода Разработчики часто используют паттерн проектирования фасад, когда система очень сложна или трудна для понимания, потому что система имеет много взаимозависимых классов или ее исходный код недоступен. Этот паттерн скрывает сложности б

Архитектура Memcached

Изображение
Memcached использует архитектуру клиент-сервер. Серверы поддерживают ассоциативный массив ключ-значение; клиенты заполняют этот массив и запрашивают его по ключу. Ключи имеют длину до 250 байт, а значения могут быть не более 1 мегабайта. Клиенты используют клиентские библиотеки для связи с серверами, которые по умолчанию предоставляют свои услуги через порт 11211. Поддерживаются как TCP, так и UDP. Каждый клиент знает все серверы; серверы не общаются друг с другом. Если клиент желает установить или прочитать значение, соответствующее определенному ключу, клиентская библиотека сначала вычисляет хэш ключа, чтобы определить, какой сервер использовать. Это дает простую форму сегментирования и масштабируемой архитектуры без совместного использования ресурсов на всех серверах. Сервер вычисляет второй хэш ключа, чтобы определить, где хранить или прочитать соответствующее значение. Серверы хранят значения в оперативной памяти; если серверу не хватает оперативной памяти, он отбрасывает самые с