版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.前言 在前面的文章中, 《REDIS-CLUSTER集群创建内部细节详解》 萌叔创建一个Redis集群。 这篇文章,我会为集群添加2个节点,并介绍slot的迁移过程。 2.集群扩容 添加主节点127.0.0.1:7006 redis-cli –cluster add-node 127.0.0.1:7006 127.0.0.1:7000 添加从节点127.0.0.1:7007(并指定其Master节点) redis-cli –cluster add-node 127.0.0.1:7007 127.0.0.1:7000 –cluster-slave –cluster-master-id 86f3cb72813a2d07711b56b3143ff727911f4e1e 新添加的节点上并没有slot分布,需要通过命令让slot重新分布 root@BJ-02:~/cluster-test/7007# redis-cli –cluster reshard 127.0.0.1:7000 >>> Performing Cluster Check (using node 127.0.0.1:7000) S: 7eb7ceb4d886580c6d122e7fd92e436594cc105e 127.0.0.1:7000 slots: (0 slots) slave… 继续阅读 REDIS-CLUSTER集群slot迁移过程分析

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 本文基于redis 6.2.7 1.引言 Redis-Cluster集群的搭建非常简单。搭建过程见参考资料1。 执行 redis-cli –cluster create 127.0.0.1:7000 127.0.0.1:7001 \ 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ –cluster-replicas 1 root@BJ-02:~/cluster-test# redis-cli –cluster create 127.0.0.1:7000 127.0.0.1:7001 \ > 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ > –cluster-replicas 1 >>> Performing hash slots allocation on 6… 继续阅读 Redis-Cluster集群创建内部细节详解

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 引言 我们都知道在Redis-Cluster集群模式下,集群中有18634个slot,slot分布在集群多个实例上,当执行一个Command时,Redis客户端会提取Command中的key 根据下面的算法得出key所属的slot slot=CRC16(key)&16383 在根据客户端中的路由表,找到slot所在的Redis实例 这里的路由表存储的就是 slot -> redis-instance 那么问题来了redis客户端是如何得到这个路由表的呢? 2. 分析 下面以go-redis/redis的代码为例,谈谈Redis客户端如何获取和维护slot路由信息。 2.1 存储结构 type clusterClient struct { opt *ClusterOptions nodes *clusterNodes state *clusterStateHolder // 在这里 cmdsInfoCache *cmdsInfoCache //nolint:structcheck } type clusterState struct { nodes *clusterNodes Masters []*clusterNode Slaves… 继续阅读 Redis-Cluster集群模式下Redis客户端如何获得slot的路由信息

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.前言 BoltDB是一个纯Golang实现的极简的key/value数据库。 传送门:boltdb/bolt 主库从2018年起就不再更新了。但它有2个衍生版本 hashicorp/raft-boltdb和etcd-io/bbolt分别被使用在Consul和Etcd。另外其它使用BoltDB的项目 BoltDB之所以能够得到广泛的应用,最大原因是它足够轻量,核心代码只有4000多行,另外大多数关系数据库(SQLite 除外)都需要在应用程序之外独立运行服务。比如MySQL你需要启动MySQL Server,这样就增加了额外的维护成本。而BoltDB可以嵌入在应用程序之中,同生同死。 本文萌叔会把重点放在BoltDB的事务机制的实现上 2. 事务并发控制关系 在BoltDB中官方的描述是有2中类型的事务,读写事务和读事务 2.1 读写事务包含 Bucket.Put()和Bucket.Delete() 等操作 func (b *Bucket) Put(key []byte, value []byte) error func (b *Bucket) Delete(key []byte) error 2.2 读事务包含 Bucket.Get() 等操作 func (b *Bucket) Get(key []byte) []byte 注意:… 继续阅读 BoltDB-MVCC的一种极简实践

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 之所以写这篇文章是因为我已经在不止一个群里,看到有人问如何在ES中存储关联关系。 2. 答案 你可能会在网上看到有说Join datatype和Nested data type的,但是其实这都不是ES该有的玩法。 Join datatype和Nested data type都会涉及多次查询的开销 Join datatype本身的数据就是在不同的表中,对于分布式数据库,还涉及数据从不同的节点上拉取和组装的开销。 那么应该怎么做?答案就是用冗余的宽表来存储关联关系 举例说明 假如我需要在ES中存储的实体有书籍、书籍有作者信息、书名等等信息,显然实体之间有如下关系 如果在传统的关系型数据库中,就需要创建2张表,一张表表示作者,一张表代表书。但是对于nosql数据库,只需要一张表(书)即可,doc结构形如: { “name”:”zhangsan”, “publisher_identifier”: “xxx-xxxx-xxx” “author”:{ “name”: “jobs”, “phone”: “111111111” } } 作者信息作为书的属性存储在一起,放一个doc中即可。 这样的做法必然是会带来数据冗余,但是以空间换时间,查询速度就有了保障。 现代的nosql数据库大多应对的海量数据的存储查询的问题,因此大都是分布式结构。在这种情况下,整体的设计方案必须足够简单,才能够易于维护和扩展。同样的做法,也完全适用于HBase。 3. 说几句某些人可能不爱听的话 ES集群的使用成本其实是很贵的,用了就别怕贵,觉得烧钱就别用 ES自身的性能优化工作做得还是很好的,对大多数人而言,不需要考虑优化,性能不够,就老老实实的加硬件就行。高版本相比低版本性能和稳定性都有很大的提升,优先考虑高版本 SSD对ES的性能提升非常明显(便宜不一定不是好货,但好货一定不便宜) 4. 参考资料 1.Join… 继续阅读 elasticsearch如何存储关联关系?

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 分布式锁的场景,大家应该都有遇到过。比如对可靠性有较高要求的系统中,我们需要做主备切换。这时我们可以利用分布式锁,来做选主动作,抢到锁作为主,执行对应的任务,剩余的实例作为备份 redis和zookeeper都可以用来做分布式锁,典型的如redis,可以使用SETNX命令来实现分布式锁。本文将介绍基于consul的分布式锁实现 2. 例子 测试例子 test_lock.go package main import ( “github.com/hashicorp/consul/api” “log” “strconv” “sync” “time” ) func main() { wg := &sync.WaitGroup{} for i := 0; i < 3; i++ { wg.Add(1) go tryLock(“mylock”, “session”+strconv.Itoa(i), wg) } wg.Wait() }… 继续阅读 玩转CONSUL(2)–分布式锁

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1.引言 在监控系统中,海量的监控数据如何存储,一直是设计人员所必须关心的问题。OpenTSDB选择了Hbase;Open-Falcon选择了RRD(round-robin database)。Prometheus另辟蹊径,借鉴了facebook的paper(参考资料2),设计了自己的TSDB(time series database)。本文试图简单介绍TSDB中使用的2个压缩算法 2. 简单的聊聊TSDB的文件结构 值得一提的是在prometheus中 1)数据是没有做预聚合的,所有的聚合操作都是在查询阶段进行。 据笔者观察查询的时间跨度如果超过7d,速度就会变得比较慢(3 ~ 5秒) 2)Prometheus数据都是单机存储的,数据存在丢失的可能,最近产生的数据存储在内存中,历史数据落在硬盘上,默认数据存储15天。 可以使用storage.tsdb.retention.time来修改数据存储的跨度 –storage.tsdb.retention.time=7d 3) 文件结构 ├── 01D5X2A81S8FMS16S5Q1GWNQDE │   ├── chunks // chunk数据 │   │   └── 000001 │   ├── index // 索引文件 │   ├── meta.json // 人类可读的文件 │   └── tombstones… 继续阅读 玩转Prometheus(3)–数据存储

ES内部分享 1. ES简介 ElasticSearch是Elastic公司开发的开源分布式搜索引擎 开源 分布式 全文检索 OLAP(结合kibana使用) Resful API NoSQL database 1.1 和Lucene的关系 { “name”: “uf_-1wJ”, “cluster_name”: “UT”, “cluster_uuid”: “xvGp84DyQVOSxLXP43oDpA”, “version”: { “number”: “6.2.4”, “build_hash”: “ccec39f”, “build_date”: “2018-04-12T20:37:28.497551Z”, “build_snapshot”: false, “lucene_version”: “7.2.1”, “minimum_wire_compatibility_version”: “5.6.0”, “minimum_index_compatibility_version”: “5.0.0” }, “tagline”: “You Know, for Search” } 简单而言,ES是Lucene的分布式版本,当然扩充了接口和在线分析功能 1.2 基本概念 1.2.1 索引层面 index… 继续阅读 ES内部分享

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 前几天有人在群里问,es是否可以指定某个字段为路由值。ES自定义的doc的路由,不过es的操作是,在写入一个doc时,指定doc的routing key。 2. 例子 2.1 创建一个新的index PUT /my_index2 { “settings”: { “index”: { “number_of_shards”: 2, “number_of_replicas”: 1 } } } index只有2个shard,shard 0和 shard 1 2.2 设置mapping PUT /my_index2/_mapping/student { “_routing”: { “required”: true }, “properties”: { “name”: { “type”:… 继续阅读 elasticsearch中自定义doc的路由(routing)规则

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 总述 这个库的目标是为了能够简单粗暴的实现分布式限频功能, 类似于ID生成器的用法, client每次从Redis拿回-批数据(在这里只是一个数值)进行消费, 只要没有消费完,就没有达到频率限制。 English README 优势 依赖少,只依赖redis,不需要专门的服务 使用的redis自己的时钟,不需要相应的服务器时钟完全一致 线程(协程)安全 系统开销小,对redis的压力很小 安装 go get github.com/vearne/ratelimit 用法 1. 创建 redis.Client 依赖 “github.com/go-redis/redis” client := redis.NewClient(&redis.Options{ Addr: “localhost:6379”, Password: “xxx”, // password set DB: 0, // use default DB }) 2. 创建限频器… 继续阅读 基于redis的分布式限频库