Ryo's blog

分类 · Middleware

首页

关于

归档

Net

网络基础(三):P2P 内网穿透

一、背景最近在折腾家里的NAS,然后想在外网上访问家里NSA的资源。NAS其实都提供了内网穿透的功能,但是他们的解决方案一般都是所有流量都会走他们的第三方的服务器。一个是可能不安全,二是带宽有限。我要下载家里的资源速度会很慢,所以不太想用这种方案。 如果家里的光猫/路由器拨号上网有公网IP,可以直接通过家里宽带的公网IP访问,在光猫/路由器里面配置下端口转发就行了。但是我家里宽带升级到1000MB后就没有动态公网IP,所以这个方案也走不通。 网上查了下,也有很多人找宽带客服投诉以后,就给下发公网IP了的Case。 于是我也尝试找宽带客服咨询了下,问能不能给我申请一个动态公网IP,IPV6的也可以,客服明确告知说申请不了。这条路走不通,只能放弃。 然后就想到N年前做端上APP的时候,做了个UDP的内网穿透能力..

更多
ele

MySQL 基础

其他 MySQL 相关技术沉淀文章 MySQL Insert 死锁问题研究 MySQL 自增列 Duplicate Error 问题分析 MySQL DateTime和Timestamp时区问题 一、基础1.1 常用索引有哪些普通索引、唯一索引、主键索引、组合索引、全文索引 1.2 聚集索引和非聚集索引区别聚集索引(Clustered Index)和非聚集索引(Non-clustered Index)是两种不同类型的数据库索引,它们的区别如下: 聚集索引(Clustered Index): 聚集索引中的数据行和索引的顺序相同,即它将数据行本身和索引按照相同的排序方式存储在一起。 一个表只能有一个聚集索引,因为数据行只能以一种顺序存储。 聚集索引通常用主键建立,但也可以使用其他具有唯一约束的列。 数据..

更多
ele

缓存基础技术

其他 Redis 相关技术沉淀文章 Redis 源码分析(一) :sds Redis 源码分析(二) :ADList Redis 源码分析(三) :dict Redis 源码分析(四) :intset Redis 源码分析(五) :ziplist Redis 源码分析(六) :quciklist Redis 源码分析(七) :skiplist Redis 高可用解决方案总结 基础1.1 Redis 常用的数据结构Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 Sting 、SDS(embstr、raw) List qucklist (ziplist、linklist) Set (dict、 ..

更多
MySQL

MySQL 自增列 Duplicate Error 问题分析

一、背景最近我们在做线上的数据迁移测试(可以理解就是把A数据中心的数据迁移到B数据中心,A和B数据中心的MySQL是同构的,迁移过程中,A、B的MySQL都有正常的业务数据写入。每次我们触发迁移的时候,就有业务方反馈他们写入数据的时候就会有Error 1062: Duplicate entry 'xxx' for key 'PRIMARY'这样的错误。业务方同学还反馈他们写数据的时候并没有指定ID,所以他们对这样的报错比较困惑,具体他们的数据写入的伪代码如下: type Data struct { ID int64 `gorm:"primaryKey;column:id"` PageID string `gorm:"column:page_id`..

更多
loading..
MySQL

MySQL DateTime和Timestamp时区问题

一、背景最近负责一个数据传输的项目,其中一个需求就是能把一个DB里面的数据拉出来 ,然后回放到另外一个同构的DB。两个DB的服务不在一个时区(其实这不是重点),可能配置不同。之前有过类似的项目,当时是基建的同事负责做数据同步,同步过去以后DateTime、Timestamp字段的时区信息都丢了。老板让我调研下问题根因,不要踩之前的坑。 最早的时候看了下同事写的当时MySQL时区信息丢失的问题总结文档,文档里面当时把DateTime和Timestamp两个时区问题混为一起了,也没分析本质原因,导致我当时没看太明白,然后的武断的认为,之所以时区丢失了,是因为基础组件同步DateTime和Timestamp的时候同步的是字符串,比如2021-11-27 10:49:35.857969这种信息,我们传输的时候..

更多
Envoy

Envoy 编译调试

Debian9 上编译调试主要参考Envoy官方的Bazel编译文档 下载bazelisk-linux-amd64 sudo wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 sudo chmod +x /usr/local/bin/bazel 安装依赖 sudo apt-get install \ autoconf \ automake \ cmake \ curl \ libtool \ make \ ninja-build \ patch \ ..

更多
BookETCD

《ETCD实战》

摘录与 《ETCD实战》 背景ectd 常见问题 etcd 基础 etcd 实践 etcd v2 功能 etcd v2 存在的问题 第一,etcd v2 不支持范围查询和分页。分页对于数据较多的场景是必不可少的。在 Kubernetes 中,在集群规模增大后,Pod、Event 等资源可能会出现数千个以上,但是 etcd v2 不支持分页,不支持范围查询,大包等 expensive request 会导致严重的性能乃至雪崩问题。 第二,etcd v2 不支持多 key 事务。在实际转账等业务场景中,往往我们需要在一个事务中同时更新多个 key。 然后是 Watch 机制可靠性问题。Kubernetes 项目严重依赖 etcd Watch 机制,然而 etcd v2 是内存型、不支持保存 key 历史版本的..

更多
MySQL

MySQL Insert 死锁问题研究

背景不想看废话的,建议直接去最后看死锁的本质原因。 问题背景线上一个很简单结构的表,报insert死锁,这个表基本上只有insert操作,所以引出一个问题insert 和insert之间为什么会死锁? 顺便说下我们线上库的隔离级别都是RC,日志格式是ROW,我下面所有测试都是在RC下。 *** (1) TRANSACTION: TRANSACTION 2404187192, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 8 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 118913019, OS thread handle 140411115681..

更多
BookRedis

《Redis核心技术与实战》

数据结构Redis数据结构简单来说,底层数据结构一共有 6 种,分别是简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。它们和数据类型的对应关系如下图所示: 全局哈希表 因为这个哈希表保存了所有的键值对,所以,我也把它称为全局哈希表。哈希表的最大好处很明显,就是让我们可以用 O(1) 的时间复杂度来快速查找到键值对——我们只需要计算键的哈希值,就可以知道它所对应的哈希桶位置,然后就可以访问相应的 entry 元素。 渐进式 rehash简单来说就是在第二步拷贝数据时,Redis 仍然正常处理客户端请求,每处理一个请求时,从哈希表 1 中的第一个索引位置开始,顺带着将这个索引位置上的所有 entries 拷贝到哈希表 2 中;等处理下一个请求时,再顺带拷贝哈希表 1 中的下一个索引位置的 entr..

更多
BookMySQL

《MySQL实战45讲》

binlog && redo log什么是 binlog binlog 是逻辑日志,记录的是这个语句的原始逻辑/变化,比如“给 ID=2 这一行的 c 字段加 1 ”。 binlog 是追加写,不会覆盖之前的数据,可以提供完整的数据归档的能力。 什么是 redo log redo log 是物理日志,记录的是“在某个数据页上做了什么修改”; redo log 提供 crash-safe 能力。 一般只有4G ,4个文件,循环复写。 binlog 和 redo log 不同点因为最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插..

更多
Redis

Redis 高可用解决方案总结

一、主从复制什么是主从复制我们正常在项目中对redis进行应用,一般都不会是单点的。因为,单点的宕机即不可用,不能保证可用性。另外,单点redis读写指令都会打到同一个服务里面,也会影响性能。在通常的应用中,对redis的读操作远远多于写操作,所以,我们一般会选择“一主多从”的集群策略。 主中的数据有两个副本(replication)即从redis1和从redis2,即使一台服务器宕机其它两台服务也可以继续提供服务。 主中的数据和从上的数据保持实时同步,当主写入数据时通过主从复制机制会复制到两个从服务上。 只有一个主redis,可以有多个从 redis。 主从复制不会阻塞master,在同步数据时,master可以继续处理client请求。 一个可以即是主又是从,如下图: 主从复制过程一般当slav..

更多
Redis

Redis 源码分析(七) :skiplist

一、skiplist由来skiplist本质上也是一种查找结构,用于解决算法中的查找问题(Searching),即根据给定的key,快速查到它所在的位置(或者对应的value)。 我们在《Redis内部数据结构详解》系列的第一篇中介绍dict的时候,曾经讨论过:一般查找问题的解法分为两个大类:一个是基于各种平衡树,一个是基于哈希表。但skiplist却比较特殊,它没法归属到这两大类里面。 这种数据结构是由William Pugh发明的,最早出现于他在1990年发表的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees》。对细节感兴趣的同学可以下载论文原文来阅读。 skiplist,顾名思义,首先它是一个list。实际上,它是在有序链表的基础..

更多
Redis

Redis 源码分析(六) :quciklist

一、什么是quicklist由于考虑到链表adlist的附加空间相对太高,prev和next指针就要占去 16 个字节 (64bit系统的指针是8个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。 quicklist是一个3.2版本之后新增的基础数据结构,是redis自定义的一种复杂数据结构,将ziplist和adlist结合到了一个数据结构中。主要是作为list的基础数据结构。在3.2之前,list是根据元素数量的多少采用ziplist或者adlist作为基础数据结构,3.2之后统一改用quicklist,从数据结构的角度来说quicklist结合了两种数据结构的优缺点,复杂但是实用: 链表在插入,删除节点的时间复杂度很低;但是内存利用率低,且由于内存不连续容易产生内存碎片..

更多
Redis

Redis 源码分析(五) :ziplist

一、前言ziplist是redis节省内存的典型例子之一,这个数据结构通过特殊的编码方式将数据存储在连续的内存中。在3.2之前是list的基础数据结构之一,在3.2之后被quicklist替代。但是仍然是zset底层实现之一。 二、存储结构压缩表没有数据结构代码定义,完全是通过内存的特殊编码方式实现的一种紧凑存储数据结构。我们可以通过ziplist的初始化函数和操作api来倒推其内存分布。 #define ZIP_END 255 #define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl))) // 获取ziplist的bytes指针 #define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint..

更多
Redis

Redis 源码分析(四) :intset

一、什么是intsetintset是Redis内存数据结构之一,用来实现Redis的Set结构(当集合元素不大于设定值并且元素都是整数时,就会用intset作为set的底层数据结构),它的特点有: 元素类型只能为数字。 元素有三种类型:int16_t、int32_t、int64_t。 元素有序,不可重复。 intset和sds一样,内存连续,就像数组一样。 二、数据结构定义typedef struct intset { uint32_t encoding; // 编码类型 int16_t、int32_t、int64_t uint32_t length; // 长度 最大长度:2^32 int8_t contents[]; // 柔性数组 } intset; enco..

更多
Redis

Redis 源码分析(三) :dict

一、什么是dictdict (dictionary 字典),通常的存储结构是Key-Value形式的,通过Hash函数对key求Hash值来确定Value的位置,因此也叫Hash表,是一种用来解决算法中查找问题的数据结构,默认的算法复杂度接近O(1),Redis本身也叫Remote Dictionary Server(远程字典服务器),其实也就是一个大字典,它的key通常来说是String类型的,但是Value可以是String、Set、ZSet、Hash、List等不同的类型,下面我们看下dict的数据结构定义。 二、Redis Dict数据结构 从上图可以看出与dict相关的关键数据结构有三个,分别是: dict是Redis中的字典结构,包含两个dictht。 dictht表示一个Hash表。 dic..

更多
Redis

Redis 源码分析(二) :ADList

概述ADList(A generic doubly linked list)是 redis 自定义的一种双向链表,广泛运用于 redisClients 、 redisServer 、发布订阅、慢查询、监视器等。(注:3.0及以前还会被运用于list结构中,在3.2以后被quicklist取代)。 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度。 链表在Redis 中的应用非常广泛,比如列表键的底层实现之一就是链表。当一个列表键包含了数量较多的元素,又或者列表中包含的元素都是比较长的字符串时,Redis 就会使用链表作为列表键的底层实现。 链表结构是 Redis 中一个常用的结构,它可以存储多个字符串 它是有序的 能够存储2的32次方减一个节点(超过 40..

更多
Redis

Redis 源码分析(一) :sds

什么是sds字符串是Redis中最为常见的数据存储类型,其底层实现是简单动态字符串sds(simple dynamic string),是可以修改的字符串。 它类似于Java中的ArrayList,它采用预分配冗余空间的方式来减少内存的频繁分配。 数据结构// 3.0及以前 struct sdshdr { // 记录buf数组中已使用字节数量 unsigned int len; // 记录buf数组中未使用的字节数量 unsigned int free; // 字节数组,存储字符串 char buf[]; }; // >=3.2 struct __attribute__ ((__packed__)) sdshdr5 { unsigned cha..

更多
MySQL

MySQL 索引那些事

1. MySQL 常见几种索引类型1.1 普通索引,是最基本的索引,它没有任何限制。它有以下几种创建方式: (1)直接创建索引 CREATE INDEX index_name ON table(column(length)) (2)修改表结构的方式添加索引 ALTER TABLE table_name ADD INDEX index_name ON (column(length)) (3)创建表的时候同时创建索引 CREATE TABLE `table` ( `id` int(11) NOT NULL AUTO_INCREMENT , `title` char(255) CHARACTER NOT NULL , `conten..

更多
MySQL

MyISAM和InnoDB区别和应用场景

什么是MyISAM 和InnoDB MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM所改良。虽然性能极佳,但却有一个缺点:不支持事务处理(transaction)。 InnoDB,是MySQL的数据库引擎之一,为MySQL AB发行binary的标准之一。InnoDB由Innobase Oy公司所开发,2006年五月时由甲骨文公司并购。与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能,类似于PostgreSQL。 MyISAM:它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且..

更多
Consul

服务发现之Consul

consul是一个可以提供服务发现,健康检查,多数据中心,Key/Value存储等功能的分布式服务框架 用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul的方案更”一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。使用起来也较为简单。Consul用Golang实现,因此具有天然可移植性(支持Linux、Windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与Docker等轻量级容器可无缝配合。 Consul 的使用场景 docker 实例的注册与配置共享 coreos 实例的注册与配置共享 vitess 集群 SaaS 应用的配置共享 与 confd ..

更多