分布式缓存Redis之二进制安全

写在前面

本学习教程所有示例代码见GitHub:https://github.com/selfconzrr/Redis_Learning

什么是二进制安全?Redis的String为什么是二进制安全的?

维基百科:

  Binary-safe is a computer programming term mainly used in connection with string manipulating functions. A binary-safe function is essentially one that treats its input as a raw stream of data without any specific format. It should thus work with all 256 possible values that a character can take (assuming 8-bit characters).

  二进制安全是一种主要用于字符串操作函数相关的计算机编程术语。一个二进制安全功能(函数),其本质上将操作输入作为原始的、无任何特殊格式意义的数据流。其在操作上应包含一个字符所能有的256种可能的值(假设为8比特字符)

  那么什么是特殊格式呢?

  Special characters:Most functions are not binary safe when using any special or markup characters, such as escape codes or those that expect null-terminated strings. A possible exception would be a function whose explicit purpose is to search for a certain character in a binary string.

  大多数的函数当其使用任何特别的或标记字符,如转义码,那些期望 null 结尾的字符串(如C语言中的字符串),不是二进制安全的。一个可能的例外是该函数的明确的目的是在某二进制字符串搜索某特定字符。

Data format:
  Binary safe functions are required when working with data of unknown format (otherwise the format would not be preserved) such as arbitrary files, encrypted data, and the like. The length of the data must be known by the function in order to operate on the entirety of the data.

  在处理未知格式的数据(尽管此格式无需保存),例如随意的文件、加密数据及类似情况时,二进制安全功能是必须的。函数必须知道数据长度,以便函数操作整体数据。

密码学范畴:

  二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改、破译等,如果被攻击,能够及时检测出来。 二进制安全包含了密码学的一些东西,比如加解密、签名等。

其他解释:

  二进制安全功能(binary-safe function)是指在一个二进制文件上所执行的不更改文件内容的功能或者操作。这能够保证文件不会因为某些操作而遭到损坏。二进制数据是按照一串0和1的形式编码的。而绝大多数的程序会给某些特殊的比特串赋予不同的格式代码,所以当用户使用一个程序读取一个二进制文件时,该文件会被按照这个程序的规则进行解释。如果这个程序所使用的格式编码和文件被写入的格式编码一致,那么这个文件可以被正常读取,否则该文件的格式代码之中会被附加一些无意义的符号,也可能会导致文件损坏。如果最严重的情况发生,这样的操作会因为损坏导致你的数据永久丢失。所以你应该将重要的文件保存在只读性的存储介质上,例如光盘。

  所以根据维基的解释,可以这么理解:

  它并不像C语言那样,使用’\0’作为判定一个字符串的结尾,所以如果你保存的字符串内存在’\0’,c语言自会识别前面的数据,后面的就会被忽略掉,所以说是不安全的。而redis是使用了独立的len,这样可以保证即使存储的数据中有’\0’这样的字符,它也是可以支持读取的。而且前面介绍到Redis的string可以支持各种类型(图片、视频、静态文件、css文件等)

struct sdshdr{
        int len;//buf数组中已经使用的字节的数量,也就是SDS字符串长度
        int  free;//buf数组中未使用的字节的数量
        char buf[];//字节数组,字符串就保存在这里面
};

  redis通过定义上述结构体的方式,扩展了C语言底层字符串的缺点,字符串长度的获取时间复杂度从原来的O(N)变成了O(1),另一方面也可以通过free的动态改变来减少内存的分配。需要强调一点的是buf数组不是存储的字符,而是二进制数组,因为C语言字符串中间是不能出现空字符的,而二进制数据中间很有可能会有空字符,所以C语言是二进制不安全的,而redis又是二进制安全为了存储多种类型的数据,redis就直接把所有数据当作二进制来存储,这样就可以存储媒体文件和字符串,所以SDS虽然叫简单动态字符串,但是它可不只是用来保存字符串。SDS在Redis中是实现字符串对象的工具。当你对该字符串取值时是通过len属性判断实际内容的长度,然后取的值。拼接字符串时是追加到free空间中的。

  **简单总结:**二进制安全的意思就是,只关心二进制化的字符串,不关心具体格式,只会严格的按照二进制的数据存取,不会妄图以某种特殊格式解析数据。

  Redis的简单动态字符串SDS对比C语言的字符串char*,有以下特性:

  • 可以在O(1)的时间复杂度得到字符串的长度
  • 可以高效的执行append追加字符串操作
  • 二进制安全

  原理:SDS通过判断当前字符串空余的长度与需要追加的字符串长度,如果空余长度大于等于需要追加的字符串长度,那么直接追加即可,这样就减少了重新分配内存操作;否则,先用sdsMakeRoomFor函数对SDS进行扩展,按照一定的机制来决定扩展的内存大小,然后再执行追加操作,扩展后多余的空间不释放,方便下次再次追加字符串,这样做的代价就是浪费了一些内存,但是在Redis字符串追加操作很频繁的情况下,这种机制能很高效的完成追加字符串的操作。

------至所有正在努力奋斗的程序猿们!加油!!
有码走遍天下 无码寸步难行
1024 - 梦想,永不止步!
爱编程 不爱Bug
爱加班 不爱黑眼圈
固执 但不偏执
疯狂 但不疯癫
生活里的菜鸟
工作中的大神
身怀宝藏,一心憧憬星辰大海
追求极致,目标始于高山之巅
一群怀揣好奇,梦想改变世界的孩子
一群追日逐浪,正在改变世界的极客
你们用最美的语言,诠释着科技的力量
你们用极速的创新,引领着时代的变迁

——乐于分享,共同进步,欢迎补充
——Any comments greatly appreciated
——诚心欢迎各位交流讨论!QQ:1138517609
——CSDN:https://blog.csdn.net/u011489043
——简书:https://www.jianshu.com/u/4968682d58d1
——GitHub:https://github.com/selfconzrr

你可能感兴趣的:(分布式缓存Redis学习,Redis,分布式缓存,二进制安全,String)