本文档翻译自: http://redis.io/topics/protocol 。 Redis 协议在以下三个目标之间进行折中: 易于实现 可以高效地被计算机分析(parse) 可以很容易地被人类读懂 网络层 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 。 客户端和服务器发送的命令或数据一律以 \r\n (CRLF)结尾。 请求 Redis 服务器接受命令以及命令的参数。 服务器会在接到命令之后,对命令进行处理,并将命令的回复传送回客户端。 新版统一请求协议 新版统一请求协议在 Redis 1.2 版本中引入, 并最终在 Redis 2.0 版本成为 Redis 服务器通信的标准方式。 你的 Redis 客户端应该按照这个新版协议来进行实现。 在这个协议中, 所有发送至 Redis 服务器的参数都是二进制安全(binary safe)的。 以下是这个协议的一般形式: *<参数数量> CR LF $< 继续阅读 >>


杜肖孟 18/06/28 17:41:22
什么是string_view std::string_view是C++ 17标准中新加入的类,正如其名,它提供一个字符串的视图,即可以通过这个类以各种方法“观测”字符串,但不允许修改字符串。由于它只读的特性,它并不真正持有这个字符串的拷贝,而是与相对应的字符串共享这一空间。即——构造时不发生字符串的复制。同时,你也可以自由的移动这个视图,移动视图并不会移动原定的字符串。 正因这些特性,当你不需要改变字符串时,应当抛弃原来使用的const string而采用新的string_view,这样可以避免多余的字符串拷贝。 构造 std::string_view允许通过C风格的字符串、字符串字面量、std::string或者其他的string_view进行构造。在构造的同时允许指定“大小”。 const char *cstr_pointer = "pointer"; char cstr_array[] = "array"; std::string stdstr = "std::string"; s 继续阅读 >>


娄泽豪 18/06/26 21:55:29
注:本篇博客只是讲述了一致性哈希的思想,我们会在之后讲述分布式哈希表以及一致性哈希的一种实现(Chord算法)。 什么是一致性哈希算法? 引用自维基百科: 一致性哈希是一种特殊的哈希算法。在使用一致哈希算法后,哈希表槽位数(大小)的改变平均只需要对 K/n个关键字重新映射,其中K是关键字的数量,n是槽位数量。然而在传统的哈希表中,添加或删除一个槽位几乎需要对所有关键字进行重新映射。 总结:一致性哈希算法主要关注的是在分布式架构中,当节点数目发生变化的时候(增加/删除),怎样使再哈希的数据量最少。 一致性哈希的引出 在分布式系统中,节点的宕机、某个节点加入或者移出集群是常事。对于分布式存储而言,假设存储集群中有10台机器(node),如果采用传统Hash方式对数据分片(item)(即数据根据哈希函数映射到某台机器上存储),哈希函数应该是这样的:hash(item) % 10。根据上面的介绍,当node数发生变化(增加、移除)后,数据会被重新“打散”,导致大部分数据不能落到原 继续阅读 >>


董恒毅 18/06/26 21:06:58
C++ 17标准已经发布了有一段时间了(甚至于后一个版本C++ 20也在路上了),最近终于得空(懒癌治愈),查阅了相关资料,简单上手一下。感觉到,一个是“现代”C++和C语言确实已经是天差地别,另一个就是标准库中的东西以及新语法确实更加方便我们编程了。虽然这些特性也许很长一段时间内都不一定用得上,然而学习一下总是好的,并且,体验一下“更现代”的C++的感觉也不错。 带初始化的选择语句 这个特性用于if和switch语句中,现在允许在这两个选择语句中声明并初始化一个变量,该变量在整个选择语句中都可用。这个特性显然有助于代码的清晰性,现在你可以这样写了: if (int fd = open("filename", O_RDWR | O_CREAT); fd == -1) { perror("something"); } else { // 可以继续在这里使用fd } switch (int op = getOp(); op) { case xxx: ... case 继续阅读 >>


娄泽豪 18/06/26 19:24:43
一致性哈希的原理: 作者:championhengyi 发表于 2018/06/26 11:12:58 原文链接 https://blog.csdn.net/championhengyi/article/details/80812517 阅读:10 继续阅读 >>


董恒毅 18/06/26 11:12:58
Docker 是什么 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。它属于 Linux 容器的一种封装,提供简单易用的容器使用接口。 Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker ,就不用担心环境问题。 虚拟机 与 Linux 容器 虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统。虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件。 虚拟机的缺点:资源占用多、冗余步骤多、启动慢。 Linux 容器(Linux Containers,缩写为 LXC)不是模拟一个完整的操作系统,而是对进程进行隔离。 容器的优势:启动快、资源占用少、体积小。 容器是进程级别的,有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。 继续阅读 >>


李猛 18/06/24 21:23:44
IP地址的基础知识 在TCP/IP通信中,IP地址用于识别主机和路由器。 1.IP地址的定义 IPv4地址为32位,IPv6地址为128位。(以下以IPv4为例) 将32位的IP地址分为4组,每组8位,每组间用“.”隔开,再将每组数转为十进制数。例如: 127.0.0.1 通常一块网卡只设置一个IP地址,其实也可以配置多个IP地址。一个路由器通常配置两个以上的网卡,因此可以设置两个以上的IP地址。 2.IP地址的组成 IP地址由网络标识和主机标识两部分组成。 不同段的网络标识不同;相同段内不同主机的网络标识相同,主机标识不同。从而保证了IP地址的唯一性。 对于IP地址唯一性的理解: Tnternet分为公网地址与私网地址。IP地址的唯一性是对于公网而言的,在公网中,只有IP地址是唯一的才能正确发送数据,否则会造成混乱。那我们经常看到的路由器IP为192.168.0.1或192.168.1.1,那岂不是我们的IP有可能是相同的?这是因为我们使用的路由器在为自己分配IP时就成了 继续阅读 >>


王良 18/06/23 23:26:52
 c++11增加了一个新的类型--右值引用,而移动语义是通过右值引用来匹配临时值的.  尽管不能将一个右值引用直接绑定到一个左值上,但可以通过move将一个左值显示的转换为对应的右值引用类型  move,这是一个具有迷惑性的名字,实际上,move函数并没有真正的移动对象,他只是将该对象从一个左值转换为一个右值   #include <iostream> #include <string> using namespace std; void func(string&& str) { cout << "here is func : " << str << endl; } int main() { string a = "here is a test"; func(move(a)); cout << "a : " << a << endl < 继续阅读 >>


吕子健 18/06/23 22:42:42
本质上是一个匿名的方法: 先看下面这个例子,一个传统的方法 `public int add(int x,int y){ return x+y; }` 转换为Lambda之后就是下面这个样子 (int x,int y)->x+y //表达式 (int x,int y)->{return x+y};//语句块 lamdba表达式的组成:参数列表,箭头,以及一个语句块或者是表达式. 如下 ()->{} ()为参数列表,参数的类型可以省略,Java编译器可以自动推断. 如果只有一个参数且可以被Java推断出类型,那么参数列表的括号也可以省略. Lambda表达式的类型叫做”目标类型”,他是一个”函数接口”(定义:一个接口,如果只有一个显式声明的抽象方法,那么它就是一个函数接口。一般用@FunctionalInterface标注出来(也可以不标)。) 所以可以将Lambda表达式为一个函数接口赋值,如下 Runable接口就是一个函数接口,因为他只有一 继续阅读 >>


宫展京 18/06/23 22:18:34
每次安装Linux的时候,都会要求配置交换分区,那么这个分区是干嘛的呢?不设置这个分区有什么后果?如果一定要设置,设置多大比较合适?本篇将试图回答这些问题并尽量覆盖所有swap相关的知识。 下面的所有例子都在ubuntu-server-x86_64 16.04下执行通过 什么是swap? swap space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合。简单点说,当系统物理内存吃紧时,Linux会将内存中不常访问的数据保存到swap上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问swap上存储的内容时,再将swap上的数据加载到内存中,这就是我们常说的swap out和swap in。 为什么需要swap? 要回答这个问题,就需要回答swap给我们带来了哪些好处。 对于一些大型的应用程序(如LibreOffice、video editor等),在启动的过程中会使用大量的内存,但这些内存很多时候只是在启动的时候用一下,后面的运行过程中很少再用到 继续阅读 >>


杜肖孟 18/06/23 18:18:46