使用 MySQL 实现搜索附近的人

By | 2017/05/10

背景介绍 现今地理位置功能非常普及, 在很多网站, 手机 app 等都有体现, 现实中这个功能也方便了我们的吃穿住行, 比如我们普通大众经常使用的附近的人附近的餐厅等就是基于这个功能来实现, 其可以应用到以下相关功能: 商店: 找到你当前的位置; 社交: 找到你附近的朋友; 地图: 找到附近感兴趣的地方; 从这方面来看, 如何找到当前的位置是我们的首要任务, 庆幸的是现今的很多 gps 设备可以完成该任务, 比如我们常用的手机打开 gps 功能后, 相关的 app 即可获取到经纬度地理位置信息, 我们通过经纬度即可计算出相应的地理位置, 再就是计算两个经纬度之间的距离, 等等. 其背后的技术实现值得我们持续深入的学习下去,下文会简单介绍地理位置实现的方式, 后面则着重介绍如何使用 MySQL 实现附近的人的功能. 经纬度 详见: 经纬度 首先了解经纬度需要学习下地理知识, 经纬度是经度与纬度的合称组成的坐标系统, 称为地理坐标系统, 他是利用三度空间的球面来定义地球上的空间的球面坐标系统, 能够标示地球上的任意一个位置. 如下图所示: 纬线和经线都是人类为度量方便而假设处理的辅助线. 纬线 纬线定义为地球表面某店随地球自转所形成的轨迹, 如上图所示, 任何一根纬线都是圆形而且两两平行. 纬线的长度时赤道的周长诚意纬线的纬度的余弦. 经线 经线也称子午线, 定义为地球表面连接南北两极的大圆线上的半圆弧. 任两根经线的长度相等,相交于南北两极点, 每一根经线都有其相对应的数值,称为经度, 经线指示南北方向。 距离计算… Read More »

id 生成器介绍

By | 2017/03/30

背景介绍 在一般的业务场景中, 初始的时候简单的自增数(比如MySQL 自增键)就可以很好的满足需求, 不过随着业务的发展和驱动, 尤其是在分布式的场景中, 如何生成全局的唯一 id 便成了需要慎重考虑的事情. 业务之间如何协调, 生成的序列是否还有其它需求等都需要重新设计, 下文则介绍生成唯一 id 的不同方式以及各自适用的场景. 1. twitter Snowflake 介绍 原文见: announcing-snowflake twitter 碰到的问题 twitter 使用 MySQL 存储线上的数据, 不过随着业务的发展, 现在已经成为了很大的数据库集群. 由于种种原因, 在一些细节方面, twitter 使用分布式数据库 Cassandra 或水平拆分 MySQL 来更好的服务全局的博文及帖子. Cassandra 并没有内置类似 MySQL 自增主键的功能, 这也意味着随着业务的扩张, 使用 Cassandra 很难在序列 id 方面提供一个通用的解决方案(one-size-fits-all solution), 这个问题在水平拆分 MySQL 的架构中也同样存在. 基于这些问题, twitter 提出了以下需求: 1. 每秒生成上万的… Read More »

percona UDF 介绍

By | 2017/03/24

简介 在较新的 percona 分之版本中, 其提供了三个自定义的哈希函数, 分别为 fnv_64, fnv1a_64 和 murmur_hash, 这三个函数可以提供更快速度和更小碰撞率的哈希计算, 从这点看可以用来替换 md5, crc32 等函数, 而且由于速度快、碰撞率小的特性, 这些函数也可以作为一致性哈希函数来使用. 如何安装这三个函数详见 udf_percona_toolkit. 函数介绍 大致了解这三个函数后, 再来简单说明这三个函数的相关实现. fnv 哈希算法 FNV哈希算法最早在1991年提出, 是 Fowler-Noll-Vo 的简写,其以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的. 另外现今很多流行的中间件或分布式工具都有该函数的申请, 比如 twemproxy 等工具. FNV能快速hash大量数据并保持较小的冲突率,它的高度分散使它适用于hash一些非常相近的字符串,比如URL,hostname,文件名,text,IP地址等. 现有的版本有 FNV-1 和 FNV-1a, FNV-0 已经废弃, FNV-1 和 FNV-1a 两个函数生成的 hash 值有以下两个限制(FNV offset basis 为无符号整数): 无符号整型; hash 值的位数为… Read More »

如何有效的跟踪线上 MySQL 实例表和权限的变更

By | 2017/03/20

介绍 从系统管理员或 DBA 的角度来讲, 总期望将线上的各种变更限制在一个可控的范围内, 减少一些不确定的因素. 这样做有几点好处: 1. 记录线上的库表变更; 2. 对线上的库表变更有全局的了解; 3. 如果有问题, 方便回滚操作; 从这三点来看, 有很多种方式可以实现, 比如通过 migrate 等工具强制所有的操作都以统一的方式执行, 这需要开发人员做更多的配合, 所以这类工具在非规模话的业务场景中较难实现; 另外管理员或 DBA 也可以通过知识库比如 redmine 等类似的方式记录变更, 不过不可控因素很多, 特别依赖上线的流程, 也容易出现纰漏. 这就引申出本文要介绍的如何跟踪线上库表的变更, 下文以 MySQL 数据库介绍说明. 跟踪的方式 在 Postgresql 中, 由于触发器对各种操作都有很好的支持, 我们完全可以通过触发器的形式来记录所有 DDL 语句的变更. 与此相比, MySQL 则显得较为弱小, 我们只能以其它方式实现类似的目标. 下面以中间件, log, binlog, 注册 slave, mysqldiff 五种方式进行介绍. 1. 中间件 现有的中间件… Read More »

如何使用 iptables 来进行端口转发

By | 2017/03/08

1. 介绍 传统的端口转发工具portproxy 、rinetd 等, 这些应用工具都通过接收并转发 tcp 数据报文实现转发端口的目的, 但是都存在或多或少的缺陷, 比如不能 tcp/udp 同时支持, 难以修改数据报文的一些路由规则等. 庆幸的是我们可以通过 linux 的 iptables 的数据包过滤规则在 kernel 层面实现端口的转发. 在 iptables 的层面, 端口转发也可以称为端口映射, 是通过NAT(地址转发)的方式来修改数据包目的地址或端口, 再将报文转发到最终的主机(通常在没有公网地址的私有网络中). 通过这种方式用户既可以访问到远端的私有网络的机器(比如运行着 http 服务的主机). 2. 访问结构 我们以如下结构来讲解如何在 public A 主机中进行端口转发, 使得用户可以访问到后端的 private B 主机的 memcached 端口: note: 所有主机均为 Centos 系统, 1.1.1.1 为任意的公网地址. +——+ +———-+ +———–+ | user | ——-> |… Read More »