简析一致性哈希算法及其实现
场景业务中有 N 台 redis 缓存服务器 [0, N-1],那么对于任意一个关键字 key 的请求,我们都是做一个对 key 哈希值取模的请求分发。前台请求被分发到编号 (hash (key)% N) 这台服务器上。理想状态下,这样的缓存命中率是很高的。但当因为业务需求而增删服务节点数,例如添加一台服务器。那么原来被分配到 k 号服务器的现在会被分到 (k-1) 号服务器。这个时候几乎所有的缓存全部会被 miss 掉,造成极大的业务压力。
一致性哈希算法的目的就是,当后台增删节点时,旧的数据能够依旧计算到原来的服务器,而新数据能够按新的哈希算法分配到新服务器。
原理一致性哈希算法把 N 个服务节点映射到一个环上。对每个服务节点的 key 值进行 hash 计算,获得一个长度为 N 的数组,再把数组首尾相连,获得一个环。我们对所有的请求节点 key 作 hash 计算,会落入该环的某一个弧段,我们可以设定每个弧段上的请求节点都以顺时针最近的 Node 作为服务节点。这样增加或减少服务节点,那影响的也只是一个弧段上的请求节点,而其他弧段上的请求节点则不受影响。
这实际上就是把映射环 ...
Redis 面试题解答
对常见 Redis 面试题做个记录。
概念题什么是 RedisRedis (Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD 许可)高性能非关系型(NoSQL)的键值对数据库。
Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。
与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10 万次读写操作,是已知性能最快的 Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。
Redis 有哪些优缺点优点
读写性能优异, Redis 能读的速度是 110000 次 /s,写的速度是 81000 次 /s。
支持数据持久化,支持 AOF 和 RDB 两种持久化方式。
支持事务,Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作合并后的原子性执行。
数据结构丰富,除 ...
通过 docker 容器方式搭建 gitlab 服务
一直使用 git 来做项目版本控制,但每次新建项目都要去服务器上操作,比较麻烦,所以选用开源的 gitlab 就相当合适了。
gitlab 的自带组件比较多,例如 redis、postgresql 还有自带的 nginx 等等,中间的坑也很多,综合考量还是选用懒方法 docker 容器来安装。安全、快速。
部署环境为 Ubuntu 18.04 的局域网机器,由于是 Docker 方式部署,理论上各个环境的部署方式都是类似的。
环境准备性能要求最好是 4GB 内存以上,至少要 2GB 内存,否则卡的你怀疑人生。
安装 Docker我们从阿里源安装。
安装必要的一些系统工具
12$ apt-get update$ apt-get -y install apt-transport-https ca-certificates curl software-properties-common
安装 GPG 证书
1$ curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
写入软件 ...
从 JWT 聊聊认证
跨域认证 意指把 A 服务的认证状态可分享给 B 服务,这样单服务的 Session+cookie 的解决方案就不合适了。我们可以通过服务端搭建 session 持久化层来解决这个问题,该层由多个服务共享,这种方式对持久化层的稳定性要求较高。另一种方式是把认证数据保存在客户端。其中一种方式就是 Json Web Tokens(JWT)。
原理JWT 是初次认证时,服务器把认证信息生成一个 Json 文本,回送给用户。
12345{ "name": "andy", "authority": "admin", "expire": "201807010000000"}
往后用户与服务端通信的时候,都要发回这个 JSON 对象。服务器根据该对象来进行用户身份确认。服务器会在生成该对象时加上签名。
结构JWT 由三个部分组成。
123Header.Payload.Signature 头部。负载。签名 例:eyJhbGciOijIfdkKjf3m ...
漫谈 Javascript 模块化
js 代码 2009 年 HTML5 兴起后,前端代码的行数已经呈现井喷式发展,随着代码量的增加,模块的缺失的缺点日益凸显,Javascript 社区做了很多探索。如今 JavaScript 模块化编程的概念已经普及开来,一提起模块化,大家想到的可能是 AMD,CMD,requirejs 或 seajs。其实还有很多其他的概念。本文将会陈述下 JavaScript 模块的前世今生。
模块
模块,又称构件,是能够单独命名并独立地完成一定功能的程序语句的集合(即程序代码和数据结构的集合体)
一个独立的模块需要能够独立完成一个功能,可以引用依赖和被依赖。例如 C 语言中的库和头文件,Java 中的包,等等。
原始写法一个函数实际上就是一个模块
1234// 最简单的函数,可以称作一个模块 function add(x, y) { return x + y;}
一个更合理的模拟模块方式
1234(function (mod, $, _) { mod.add = ***; mod.sub = ***;}((window.mod = window.mod ...
对称加密和非对称加密
对称加密和非对称加密,是加密通信中常见的两个概念。wiki 的定义是:
对称密钥加密 是 密码学 中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。
非对称加密 也称 非对称加密 ,是 密码学 的一种 算法,它需要两个 密钥,一个是公开密钥,另一个是私有密钥;一个用作加密的时候,另一个则用作解密。使用其中一个密钥把 明文 加密后所得的 密文,只能用相对应的另一个密钥才能解密得到原本的明文;甚至连最初用来加密的密钥也不能用作解密。
为了便于理解。我们来举例说明。
对称加密回想起初中时代的小纸条了没,假设同学 A 想给同学 B 传一个小纸条,但是 A 离 B 隔着几个座位,需要由中间的 C 来帮忙传纸条,因为 C 是个爱打小报告的家伙,所以 A 和 B 都不想让 C 知道纸条中的具体内容是什么。于是 A 和 B 私下约定,纸条中的内容以摩尔斯编码来代替,例如要发送 “hello”,那么纸条中就写 “hello” 的摩尔斯编码 “…. . .-.. .-.. —- ”,由于 C 不知道 A 与 B 的约定转换规则,所以他即使看到了纸 ...
JavaScript 词法分析
JavaScript 引擎在代码执行前会进行词法分析,词法分析主要有三个步骤:
分析参数 -> 分析变量的声明 -> 分析函数声明
词法分析过程JavaScript 函数在运行的瞬间,会生成一个活动对象 AO(Active Object),举个例子
1234567function f1(name){ var name = 'mary'; console.log(name); function name(){} console.log(name);}f1("abc");
第一步:分析参数:
函数接收形式参数,添加到 AO 的属性,并且这个时候值为 undefined, 即 AO.name=undefined
接收实参 "abc",添加到 AO 的属性,覆盖之前的 undefined,即 AO.name='abc'
第二步:分析变量声明: 如 var name; 或 var name='mary';
如果上一步分析参数中 ...
简明 tmux 玩法教程
猫哥_kaiye | 编程笔记 十分钟学会 tmuxtmux 是一款终端复用命令行工具,一般用于 Terminal 的窗口管理。在 macOS 下,使用 iTerm2 能应付绝大多数窗口管理的需求。
如上图所示,iTerm2 能新建多个标签页(快捷键 ⌘T),也能在同一个窗口中分割出多个窗格(快捷键 ⌘D 或 ⌘⇧D)。
tmux 相比 iTerm2 的优势在于:
iTerm2 的窗格切换快捷键(⌘⌥→)容易与其他软件全局快捷键冲突(例如 Spectacle 的窗口分割快捷键),tmux 由于存在前缀快捷键,所以不存在快捷键冲突问题;
tmux 可以在终端软件重启后通过命令行恢复上次的 session ,而终端软件则不行;
tmux 简洁优雅、订制性强,学会之后也能在 Linux 上使用,有助于逼格提升。
接下来我们花十分钟来掌握下 tmux 的基础用法:
安装运行macOS 上使用 Homebrew 安装即可:
1brew install tmux
安装完成后,运行 tmux 新建一个 tmux 的会话(session),此时窗口唯一的变化是在底部会出现一个 tmux 的状态栏 ...
(转载) 阿里 Redis 开发规范笔记
本文主要介绍在使用阿里云 Redis 的开发规范,从下面几个方面进行说明。
键值设计
命令使用
客户端使用
相关工具
通过本文的介绍可以减少使用 Redis 过程带来的问题。
键值设计key 名设计可读性和可管理性以业务名 (或数据库名) 为前缀 (防止 key 冲突),用冒号分隔,比如业务名:表名:id
1ugc:video:1
简洁性保证语义的前提下,控制 key 的长度,当 key 较多时,内存占用也不容忽视,例如:
1user:{uid}:friends:messages:{mid} 简化为 u:{uid}:fr:m:{mid}。
不要包含特殊字符反例:包含空格、换行、单双引号以及其他转义字符
value 设计拒绝 bigkey防止网卡流量、慢查询,string 类型控制在 10KB 以内,hash、list、set、zset 元素个数不要超过 5000。反例:一个包含 200 万个元素的 list。非字符串的 bigkey,不要使用 del 删除,使用 hscan、sscan、zscan 方 ...
什么是微服务
微服务 - microservice 微服务是指提供单个业务功能的服务 。无独立进程,采用轻量级的通信协议,独立部署且无集中式管理。
技术角度上看,就是把一个传统的复杂软件架构拆分为若干小而独立运行(有自己的端口)微服务组成,这些独立处理组件之间通讯是通过与语言无关的 API 进行。这种做法可以将具体业务拆分为多个模块,提供充分的灵活性,大大提高了项目生命周期和开发效率。
特性 每个微服务组件都有自己分配的存储 内存和 CPU 资源,这就使得硬件利用更加易于优化和跟踪开,只要遵循微服务之间的 API 规范,微服务组件就可以组成一个完整的服务。这个服务的复杂性和扩展性是良好的,更新其中一个微服务组件不会引起连锁反应,因为微服务之间是松耦合的。
容器技术与微服务 因为有很多应用和服务部署在基于云主机的环境中,微服务架构将会严重依赖容器技术,容器隔离了微服务处理过程,将一个应用切分为一个个小的实例,这些容器中的小实例有自己的端口和虚拟化环境。广泛使用的容器技术是 Docker。
微服务架构不只是传统服务变微变小。微服务两个显著特点是:微服务本身是无状态的; ...