0

0

Redis Hashes:无需Base64,直接存储二进制数据

花韻仙語

花韻仙語

发布时间:2025-09-02 16:28:01

|

290人浏览过

|

来源于php中文网

原创

Redis Hashes:无需Base64,直接存储二进制数据

Redis Hashes支持直接存储二进制数据,无需Base64编码。其核心在于Redis的字符串类型本身是二进制安全的,而Hash的字段和值均由字符串构成,因此Hash结构自然继承了这一特性,允许用户高效、无损地存储任意字节序列。

Redis Hashes的二进制安全特性

redis是一个高性能的键值存储系统,其数据类型设计考虑了广泛的应用场景。关于二进制数据存储,redis官方明确指出其字符串类型是“二进制安全的”(binary-safe)。这意味着redis的字符串可以存储任何字节序列,从纯文本到图像、音频或任何序列化对象,而不会对其内容进行任何解释或修改。

Hash作为Redis的一种复合数据类型,它存储的是字段(field)和值(value)之间的映射关系。根据Redis的文档,Hash的字段和值都必须是字符串类型。由于Redis的字符串本身就是二进制安全的,因此逻辑上,Hash的字段和值也继承了这一特性。这意味着你可以将任何二进制数据作为Hash的值(或字段名)存储到Redis中,而无需担心数据损坏或需要额外的编码步骤。

为何无需Base64编码

在许多Web或文本协议环境中,二进制数据需要转换为文本格式才能传输或存储,Base64编码就是一种常用的解决方案。它将任意二进制数据编码为ASCII字符集中的可打印字符,从而使其能够在只支持文本的环境中安全传输

然而,Redis的客户端-服务器通信协议(RESP)以及其内部存储机制本身就是二进制友好的。当客户端(如phpredis)将数据发送给Redis服务器时,它会以字节流的形式进行传输。Redis服务器接收到这些字节流后,会将其原封不动地存储为字符串值。因此,对于Redis Hashes而言,在存储二进制数据时,执行Base64编码是完全不必要的额外步骤,它会增加数据体积(通常增大33%),消耗CPU资源进行编码和解码,并可能降低整体性能。

实战示例:使用phpredis存储和检索二进制数据

以下是一个使用phpredis库来存储和检索二进制数据的示例。我们将模拟存储一张小图片的字节数据。

WiseHome家政预约小程序
WiseHome家政预约小程序

家政服务平台系统包含家用电器安装清洗、搬家、家电维修、管道疏通、月嫂保姆、育儿陪护、上门开锁等多种服务项目,用户可以直接通过家政小程序咨询,在线预约服务类型,同时还设置有知识科普,给用户科普一些清洁保养小技巧,让用户能够足不出户就可以直接预约服务,方便又快捷。本项目使用微信小程序平台进行开发。使用腾讯专门的小程序云开发技术,云资源包含云函数,数据库,带宽,存储空间,定时器等,资源配额价格低廉,无需

下载
connect('127.0.0.1', 6379);
    echo "成功连接到Redis服务器。\n";
} catch (RedisException $e) {
    die("无法连接到Redis服务器: " . $e->getMessage() . "\n");
}

$hashKey = 'user:profile:1001';
$field = 'avatar_image_raw';

// 模拟二进制数据,例如一个小的PNG图片头部和部分数据
// 在实际应用中,这可能来自文件读取(file_get_contents)、数据库BLOB字段或网络请求
// 这里使用hex2bin来创建示例二进制数据
$binaryData = hex2bin('89504e470d0a1a0a0000000d49484452000000100000001008060000001f15c489000000017352474200aece1ce90000000467414d410000b18f0bfc6105000000097048597300000ec300000ec301c76fa8640000000774494d4507e6011c133a216f284d720000000c4944415478daedc10101000000c2a0f74f6d0000000049454e44ae426082');

echo "待存储的二进制数据长度: " . strlen($binaryData) . " 字节\n";

// 存储二进制数据到Redis Hash
// hSet方法直接接受PHP的字符串(在PHP中,字符串是字节数组)
$result = $redis->hSet($hashKey, $field, $binaryData);

if ($result !== false) {
    echo "二进制数据成功存储到Redis Hash。\n";
} else {
    echo "存储失败。\n";
    exit;
}

// 从Redis Hash中检索二进制数据
$retrievedData = $redis->hGet($hashKey, $field);

if ($retrievedData !== false) {
    echo "二进制数据成功从Redis Hash检索。\n";
    echo "检索到的数据长度: " . strlen($retrievedData) . " 字节\n";

    // 验证数据是否一致
    if ($retrievedData === $binaryData) {
        echo "存储和检索的数据完全一致,二进制安全得到验证。\n";
    } else {
        echo "数据不一致!存储或检索过程中可能发生错误。\n";
    }

    // 注意:直接echo二进制数据到终端或浏览器可能导致乱码或显示问题,
    // 因为它们通常期望可打印的文本。
    // 如果需要将此数据用于显示(如图片),通常会将其作为HTTP响应头发送,
    // 或将其保存为文件,或在前端进行Base64编码(用于data URI)。

    // 示例:将检索到的二进制数据保存为文件
    $filename = 'retrieved_avatar.png';
    file_put_contents($filename, $retrievedData);
    echo "数据已保存为文件: " . $filename . "\n";

} else {
    echo "检索失败或数据不存在。\n";
}

// 清理数据(可选)
// $redis->hDel($hashKey, $field);
// echo "已从Hash中删除字段: " . $field . "\n";

$redis->close();
?>

在这个示例中,$binaryData变量直接包含了图片的原始字节序列。$redis->hSet()方法将其作为字符串值存储,而$redis->hGet()则将其作为原始字节序列检索出来。PHP的字符串类型在内部就是字节数组,因此可以直接处理二进制数据。

注意事项与最佳实践

尽管Redis Hashes能够二进制安全地存储数据,但在实际应用中仍需考虑以下几点:

  1. 内存消耗: Redis是内存数据库。存储大量二进制数据(如大尺寸图片或视频文件)会迅速消耗服务器内存。对于非常大的文件,通常建议将文件本身存储在文件系统、对象存储(如AWS S3、MinIO)等持久化存储中,而在Redis中仅存储文件的元数据或引用(如文件路径、URL)。
  2. 网络带宽: 存储或检索大量二进制数据意味着客户端和Redis服务器之间需要传输大量数据,这会占用网络带宽,并可能增加延迟。
  3. 客户端处理: 虽然Redis本身是二进制安全的,但客户端应用程序在处理检索到的二进制数据时,仍需确保其编程语言和库能够正确处理字节流。例如,在PHP中,字符串是二进制安全的,但如果尝试直接echo非文本二进制数据到网页,可能会导致乱码或浏览器解析错误。
  4. 数据类型选择: 对于简单的二进制数据块,直接使用Redis的STRING类型(SET/GET)可能比使用HASH更简洁。HASH适用于需要将多个相关联的二进制数据(如用户头像、封面图、缩略图)归类到一个键下的场景。
  5. 原子性: HSET操作是原子性的,即整个二进制数据作为一个单元被存储或更新。

总结

Redis Hashes通过其底层字符串类型的二进制安全特性,提供了直接存储任意二进制数据的能力,无需进行Base64等额外的编码操作。这简化了开发流程,提高了存储效率,并减少了不必要的性能开销。然而,开发者在使用Redis存储二进制数据时,仍需综合考虑内存、网络和客户端处理等因素,并根据实际需求选择最合适的存储策略。对于超大文件,外部存储与Redis索引结合的方案往往更为高效和经济。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

309

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

443

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1501

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

613

2024.03.22

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 10万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号