Экспорт растрового изображенияУправляемое чтениеЭкспорт растрового изображения Подробное объяснение команды растрового изображения Сценарии применения растрового изображения Как растровые изображения хранят миллиарды данных
В нашем обычном процессе разработки будут некоторые данные логического типа, к которым необходимо получить доступ, например, запись регистрации пользователя за один год, 1, если подписано, 0, если не подписано, и для записи требуется 365 дней. Если вы используете обычный ключ/значение, каждый пользователь должен записывать записи 365. Когда есть сотни миллионов пользователей, требуемое пространство для хранения поражает. Чтобы решить эту проблему, Redis предоставляет растровую структуру данных, так что запись о ежедневной проверке занимает только один бит, 365 дней — это 365 бит, а 46 байт (чуть более длинная строка) могут быть полностью размещены.Это значительно экономит пространство для хранения.
Подробное объяснение команд растрового изображенияЭта структура данных растрового изображения имеет тип String.
阿里云:0>set muzidao muzidao"OK"阿里云:0>bitcount muzidao #字符串中bit值为1的个数"31"
скопировать код
Я нарисовал бинарную диаграмму muzidao следующим образом, с первого взгляда все понятно, операций много, прочтите пожалуйста
Каждая буква соответствует 8-битному двоичному коду.Если менее 8 бит автоматически заполняются 0, количество единиц действительно равно 31.
BITCOUNT key [start end]
Подсчитывает количество битов, установленных в 1 в данной строке.
Обычно подсчитывается вся заданная строка, задав дополнительные начальные или конечные параметры, можно сделать подсчет только по определенным битам.
Например, -1 означает последний байт, -2 означает предпоследний байт и так далее.
Выполните операцию BITCOUNT для несуществующего ключа, результат равен 0.
Возвращаемое значение: Количество битов равно 1.
阿里云:0>bitcount muzidao #字符串中bit值为1的个数"31"阿里云:0>bitcount muzidao 0 5 #前五个字符为1的个数"25"
скопировать код
GETBIT key offset
Для строкового значения, хранящегося в ключе, получите бит по указанному смещению.
Возвращает 0, если смещение больше длины строкового значения или если ключ не существует.
Возвращаемое значение: Строковое значение, указывающее бит по смещению.
阿里云:0>getbit muzidao 0 #偏移量0上的二进制数值"0"阿里云:0>getbit muzidao 1 #偏移量1上的二进制数值"1"
скопировать код
SETBIT key offset value
Устанавливает или очищает бит по указанному смещению для строкового значения, хранящегося в ключе.
Биты устанавливаются или очищаются в зависимости от параметра значения, которое может быть только 0 или 1. Другие значения ненормальны
Параметр смещения должен быть от 0 до 2^32 (битовое отображение ограничено 512 МБ).
Для операций SETBIT с большими смещениями выделение памяти может привести к блокировке сервера Redis.
Возвращаемое значение: Строковое значение, указывающее исходный сохраненный бит по смещению.
阿里云:0>setbit muzi 0 1"0"阿里云:0>setbit muzi 0 2 # 异常,不能设置2"ERR bit is not an integer or out of range"阿里云:0>setbit muzi 0 0"1"阿里云:0>getbit muzi 0 "0"阿里云:0>setbit muzi 0 1"0"阿里云:0>getbit muzi 0 "1"
скопировать код
Когда мы устанавливаем несколько смещений, данные станут шестнадцатеричными.
Взгляните на команду
阿里云:0>get muzi"� "
скопировать код
BITPOS key [start end]
Возвращает первое смещение в строке, равное 1 или 0.
Возвращает позицию, обрабатывая строку как массив байтов слева направо, первая подходящая позиция находится в позиции 0, 8, 16, +8 и т. д.
阿里云:0>bitpos muzidao 0 #第0位的offset的值"0"阿里云:0>bitpos muzidao 1 #第1位的offset的值"1"阿里云:0>bitpos muzidao 1 0 #offset值为1并从第0位开始"1"阿里云:0>bitpos muzidao 1 2 #offset值为1并从第2位开始"17"
скопировать код
Новые функции в версии 3.2
BITFIELD key [GET type offset]
BITFIELD key [SET type offset value]
BITFIELD key [INCRBY type offset increment]
BITFIELD key [OVERFLOW WRAP|SAT|FAIL]
Команда Bitfield может работать на нескольких битах одновременно в одном вызове: он принимает ряд операций, которые будут выполняться в качестве параметров, и возвращает массив в качестве ответа, каждый элемент в массиве является результатом выполнения соответствующей операции Отказ
Команда BITFIELD поддерживает максимум 64-битные целые числа со знаком и 63-битные целые числа без знака.Ограничение 63-битной длины целых чисел без знака вызвано тем, что протокол Redis в настоящее время не может возвращать 64-битные целые числа без знака.
阿里云:0>get muzidao"muzidao"阿里云:0>bitfield muzidao get i4 0 #i:有符号位 4:连续取4位 0:开始位置 1) "6"阿里云:0>bitfield muzidao get i4 2 #i:有符号位 4:连续取4位 2:开始位置 1) "-5"阿里云:0>bitfield muzidao get u4 0 #u:无符号 4连续取4位 0:开始位置 1) "6"阿里云:0>bitfield muzidao get u4 2 1) "11"阿里云:0>bitfield muzidao get i4 0 get i4 2 get u4 0 get u4 2 1) "6" 2) "-5" 3) "6" 4) "11"阿里云:0>bitfield muzidao get u64 2 1"ERR Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is."
скопировать код
get i4 0: Возьмем 4 бита от 0, то есть 0110, со знаком/без знака до десятичной до 6, 1*2^2+1*2^1 = 6, результат тот же
получить i4 2:Возьмите 4 бита из 2, то есть 1011. Бит со знаком преобразуется в десятичный до - 5. Поскольку первый бит знака равен 1, вычтите один, чтобы получить 1010, и переверните его, чтобы получить 0101, 1 * 2 ^ 2 + 1 * 2 ^ 0 = 5, из-за реверса окончательный результат равен -5, результат согласуется
get u4 2: Возьмите 4 бита из 2, то есть 1011, и беззнаковое преобразование в десятичное будет 11. Поскольку знака нет, преобразование не требуется, и результат вычисляется напрямую как 1 * 2 ^ 3 + 1 * 2 ^ 1 + 1*2 ^0 =11 Результат тот же
阿里云:0>bitfield muzidao set u4 8 920 #u无符号 4连续4位 8位开始 920新值 1) "7"阿里云:0>get muzidao"m�zidao"阿里云:0>bitfield muzidao set u8 56 119 #u无符号 8连续8位 56位开始 119新值 1) "0"阿里云:0>get muzidao"m�zidaow"
скопировать код
920 не знает, какое значение соответствует ASCII, 119 соответствует w в значении ASCII
Посмотрите на третью подинструкцию incrby, которая используется для автоматического увеличения указанного диапазона битов. Поскольку упоминается автоинкремент, может произойти переполнение. Если добавляется положительное число, возникает переполнение, а если добавляется отрицательное число, возникает потеря значимости. Обработка Redis по умолчанию является циклической. Если происходит переполнение, бит знака переполнения отбрасывается. Если это 8-битное беззнаковое число 255, оно переполнится после добавления 1, и все станет нулем. Если это 8-битное число со знаком 127, оно переполнится до -128 после добавления 1.
阿里云:0>set muzidao muzidao"OK"阿里云:0>get muzidao"muzidao"阿里云:0>bitfield muzidao incrby u4 2 1 #2位开始连续4位无符号自增 1) "12"阿里云:0>get muzidao"quzidao"
скопировать код
1011 увеличивается до 1100 = 1*2^3+1*2^2=12
WRAP: используйте метод переноса для обработки условий переполнения для целых чисел со знаком и без знака. Для целых чисел без знака перенос похож на выполнение вычисления по модулю с использованием самого значения и наибольшего целого числа без знака, которое можно сохранить, что также является стандартным поведением в C. Для целых чисел со знаком переполнение приведет к пересчету числа из наименьшего отрицательного числа, а потеря значимости приведет к пересчету числа из наибольшего положительного числа. Например, если мы увеличим целое число i8 со значением 127, мы получим результат -128.
SAT: используйте арифметику насыщения для обработки переполнения, то есть результатом вычисления потери значимости является наименьшее целочисленное значение, а результатом вычисления переполнения является наибольшее целочисленное значение. Например, если мы добавим 10 к целому числу i8 со значением 120, результатом команды будет 127, самое большое целочисленное значение, которое может хранить тип i8. И наоборот, если вычисление значения i8 вызывает потерю значимости, для значения i8 будет установлено значение -127.
FAIL: в этом режиме команда откажется выполнять вычисления, которые могут привести к состоянию переполнения или потери значимости, и вернет пользователю нулевое значение, указывающее, что вычисление не было выполнено.
Сценарии примененияЯ отчетливо помню, что когда я пользовался приложением, я входил в систему каждый день, но не входил. После входа в систему в течение 7 дней подряд я отправлю вам электронную книгу, а если я войду в систему в течение 30 дней подряд дней, я отправлю вам электронную книгу. Иногда также будет предлагать вам войти в систему более чем на 50 дней, чтобы отправить вам электронную книгу. Я думаю, что этот сценарий очень подходит для использования растровых изображений. Однажды, войдите в систему и сохраните 1, и если вы не войдете в систему, это будет 0. Подсчитать количество логинов (bitcount)
Растровые изображения подходят для хранения логических данных.Когда у бизнеса есть только два результата, растровые изображения являются лучшим выбором.
Почему мы можем хранить миллиарды данных?
Подумайте о том, чтобы поместить ключ в Redis, его значение очень велико, настолько велико, что его вторичные цифры больше, чем самый большой идентификатор пользователя, максимальное значение одного ключа в Redis составляет 512 МБ, что может достигать 4 294 967 296 бит, что достаточно для многих предприятий. необходимо, мы используем идентификатор пользователя в качестве смещения, и значение смещения в качестве активного значения может достичь нашей цели. Таким образом, для решения задачи запроса всех данных требуется только один ключ. Предполагая, что наш максимальный идентификатор равен 500 миллионам, нам нужно 500 миллионов бит, что эквивалентно всего 500 миллионам/(8*1024*1024)≈59,6 МБ памяти. Поймите преобразование памяти с первого взгляда,
Преобразование единиц измерения:
1 байт = 8 бит
1 КБ = 1024 байта
1 МБ = 1024 КБ
1 ГБ = 1024 МБ
1 ТБ = 1024 ГБ
Давайте посмотрим, почему он может сохранить целых 4,2 миллиарда, а максимальное значение одного ключа составляет 512M, что получается путем конвертации
512(M) * 1024 (Kb) * 1024(Byte) * 8(Bit) = 4 294 967 296 (бит) = 2 ^32
Во-первых, посмотрите на память машины
[root@astali redis-3.2.6]# free #未执行命令setbit testmax 4294967295 1 total used free shared buff/cache availableMem: 1883496 699516 650264 436 533716 1022744Swap: 0 0
скопировать код
total:内存总数;
used:已经使用的内存数;
free:空闲的内存数;
shared:当前已经废弃不用;
buffers Buffer:缓存内存数;
cached Page:缓存内存数。
Выполнить волну, превышающую максимальное 4294967296 исключений, значение смещения [0,4294967296 )
阿里云:0>setbit testmax 4294967296 1"ERR bit offset is not an integer or out of range"阿里云:0>setbit testmax 4294967295 1"0"
скопировать код
Память после выполнения setbit testmax 4294967295 1 выглядит следующим образом, свободная память уменьшена с 650264 до 124984
[root@astali redis-3.2.6]# free #执行命令setbit testmax 4294967295 1 之后 total used free shared buff/cache availableMem: 1883496 1224796 124984 436 533716 497464Swap: 0 0 0
скопировать код
Когда я проверил testmax с помощью Redis Desktop Manager, он сразу взорвался. Это было ужасно. Наконец, перезапуск Redis решил проблему (в конфигурации машины мало 1 процессор, 2 ГБ памяти).
Тратьте деньги на покупку услуг, платите за знания, это действительно работает, битмап упоминается в буклете старых денег самородков, так что я понимаю волну
пожалуйста, порекомендуйте
использованная литература
Старые деньги: сэкономить деньги - растровое изображение