lua

使用amoeba实现mysql读写分离

╄→гoц情女王★ 提交于 2020-10-16 18:55:00
转载马士兵连老师笔记 使用amoeba实现mysql读写分离 1、什么是amoeba? Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。 主要解决: • 降低 数据切分带来的复杂多数据库结构 • 提供切分规则并降低 数据切分规则 给应用带来的影响 • 降低db 与客户端的连接数 • 读写分离 2、为什么要用Amoeba 目前要实现mysql的主从读写分离,主要有以下几种方案: 1、 通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。 2、 通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。 3、 自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。 4、 利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。国产的开源软件,应该支持,目前正在使用

基于“typesys”实现串行脚本框架

拜拜、爱过 提交于 2020-10-15 20:46:20
文章主要介绍了用Lua实现的串行脚本框架:LT-scriptsys。分别从“灵魂拷问”、“庖丁解牛”、“学以致用”、“抛砖引玉”这四个角度来详细阐述。为了让读者朋友们能够形象且直观地感受本框架的应用,作者使用本框架重写了上一篇文章中创作的小游戏《寻宝吧,冒险者》,增强了乐趣体验,并奉上完整代码。 更多精彩文章请关注: edu.uwa4d.com 本课程是基于作者 《用Lua打造类型系统:typesys》 一文的进阶课程,需结合《用Lua打造类型系统:typesys》课程一起学习。 课程简介 1. 灵魂拷问:为什么要实现串行脚本框架? 人们总是想要更简单更快捷,当现在拥有的已经不能再满足当下的需求时,我们就会想改进,想创造,想把理想照进现实...... 当异步并行想要理清代码逻辑变得困难时,那么使用串行去编写代码,又不影响其他逻辑的执行是不是就更好呢?由此,作者选择用自己独创的的类型定义系统——typesys来实现串行脚本框架。本课程的主要内容就是讲解:串行脚本框架是如何设计、实现和应用的。 2. 庖丁解牛:脚本框架的结构与核心技术 从设计思想、串行脚本、游戏环境、框架整合四个角度展开描述,能够从文中与作者展开深度的思想交流,并在最后提供了框架的完整源码。 3. 学以致用:重写《寻宝吧,冒险者》小游戏 在作者上一篇《用Lua打造类型系统:typesys》的基础上,重写了《寻宝吧

使用redis的zset实现高效分页查询(附完整代码)

為{幸葍}努か 提交于 2020-10-14 05:04:01
一、需求 移动端系统里有用户和文章,文章可设置权限对部分用户开放。现要实现的功能是,用户浏览自己能看的最新文章,并可以上滑分页查看。 二、数据库表设计 涉及到的数据库表有:用户表TbUser、文章表TbArticle、用户可见文章表TbUserArticle。其中,TbUserArticle的结构和数据如下图,字段有:自增长主键id、用户编号uid、文章编号aid。 自增长主键和分布式增长主键如何选(题外讨论): TbUserArticle的主键是自增id,它有个缺陷是,当你的数据库有主从复制时,主从库的自增可能因死锁等原因导致不同步。不过,我们可以知道,这里的TbUserArticle的主键id不会用在其它表里,所以可以是自增id。不像用户表的主键,它就不能用自增id,因为用户表主键(uid)会经常出现在其它表中,当主从库自增不一致时,很多有uid字段的表数据在从库中就不正确了。用户表主键最好是用分布式增长主键算法生成的id(比如Snowflake雪花算法)。 那么你可能就要说了, TbUserArticle 的主键为什么不直接用雪花算法产生,不管有没有用,先让主从库主键值一致总是有恃无恐。要知道,雪花算法产生的id一般是18位,而redis的zset的score是double类型,只能表达到16位"整数"部分(精确的说是9007199254740992=2的53次方)。因此

test

六眼飞鱼酱① 提交于 2020-10-14 01:43:02
source source <?php function Hello(){ echo "hello"; } package main import ( "context" "io/ioutil" "log" "github.com/chromedp/cdproto/page" "github.com/chromedp/chromedp" ) func main() { // Start Chrome // Remove the 2nd param if you don't need debug information logged ctx, cancel := chromedp.NewContext(context.Background(), chromedp.WithDebugf(log.Printf)) defer cancel() url := "https://golangcode.com/" filename := "golangcode.png" // Run Tasks // List of actions to run in sequence (which also fills our image buffer) var imageBuf []byte if err := chromedp.Run(ctx, ScreenshotTasks(url,

Linux下nginx的yum安装、源码安装、OpenResty的源码安装

自作多情 提交于 2020-10-11 11:27:34
Linux下nginx的安装 安装环境: # cat /proc/version Linux version 3.10.0-123.el7.x86_64 ( builder@kbuilder.dev.centos.org ) ( gcc version 4.8.2 20140120 ( Red Hat 4.8.2-16 ) ( GCC ) ) #1 SMP Mon Jun 30 12:09:22 UTC 2014 # cat /etc/redhat-release CentOS Linux release 7.6.1810 ( Core ) yum安装 设置yum仓库地址 vi /etc/yum.repos.d/nginx.repo : [ nginx-stable ] name = nginx stable repo baseurl = http://nginx.org/packages/centos/ $releasever / $basearch / gpgcheck = 1 enabled = 1 gpgkey = https://nginx.org/keys/nginx_signing.key module_hotfixes = true 使用yum安装: # yum install -y nginx 安装完成后配置文件所在目录为 /etc/nginx 。

Laravel 基于redis队列的解析

柔情痞子 提交于 2020-10-09 00:22:04
为什么使用队列 使用队列的目的一般是: 异步执行 出错重试 解释一下: 异步执行 : 部分代码执行很耗时, 为了提高响应速度及避免占用过多连接资源, 可以将这部分代码放到队列中异步执行. Eg. 网站新用户注册后, 需要发送欢迎的邮件, 涉及到网络IO无法控制耗时的这一类就很适合放到队列中来执行. 出错重试: 为了保证一些任务的正常执行, 可以将任务放到队列中执行, 若执行出错则可以延迟一段时间后重试, 直到任务处理成功或出错超过N次后取消执行. Eg. 用户需要绑定手机号, 此时发送短信的接口是依赖第三方, 一个是不确定耗时, 一个是不确定调用的成功, 为了保证调用成功, 必然需要在出错后重试 Laravel 中的队列 以下分析默认使用的队列及其配置如下 默认队列引擎: redis 通过在 redis-cli 中使用 monitor 命令查看具体执行的命令语句 默认队列名: default 分发任务 此处以分发 异步通知( class XxxNotification implement ShouldQueue )为例. 在Laravel中发起异步通知时, Laravel 会往redis中的任务队列添加一条新任务 redis 执行语句 redis> RPUSH queues:default { "displayName": "App\\Listeners\

造了一个 Redis 分布锁的轮子,没想到还学到这么多东西!!!

|▌冷眼眸甩不掉的悲伤 提交于 2020-10-08 05:33:59
书接上文 上篇文章「 MySQL 可重复读,差点就让我背上了一个 P0 事故! 」发布之后,收到很多小伙伴们的留言,从中又学习到很多,总结一下。 上篇文章可能举得例子有点不恰当,导致有些小伙伴没看懂为什么余额会变负。 这次我们举得实际一点,还是上篇文章 account 表,假设 id=1,balance=1000 ,不过这次我们扣款 1000 ,两个事务的时序图如下: 这次使用两个命令窗口真实执行一把: 注意事务 2,③处查询到 id=1,balance=1000 ,但是实际上由于此时事务 1 已经提交,最新结果如②处所示 id=1,balance=900 。 本来 Java 代码层会做一层余额判断: if (balance - amount < 0) { throw new XXException("余额不足,扣减失败"); } 但是此时由于 ③ 处使用快照读,读到是个旧值,未读到最新值,导致这层校验失效,从而代码继续往下运行,执行了数据更新。 更新语句又采用如下写法: UPDATE account set balance=balance-1000 WHERE id =1; 这条更新语句又必须是在这条记录的最新值的基础做更新,更新语句执行结束,这条记录就变成了 id=1,balance=-1000 。 之前有朋友疑惑 t12 更新之后,再次进行快照读,结果会是多少。 上图执行结果

【高并发】Redis如何助力高并发秒杀系统,看完这篇我彻底懂了!!

白昼怎懂夜的黑 提交于 2020-10-05 18:08:59
写在前面 之前,我们在《 【高并发】高并发秒杀系统架构解密,不是所有的秒杀都是秒杀! 》一文中,详细讲解了高并发秒杀系统的架构设计,其中,我们介绍了可以使用Redis存储秒杀商品的库存数量。很多小伙伴看完后,觉得一头雾水,看完是看完了,那如何实现呢?今天,我们就一起来看看Redis是如何助力高并发秒杀系统的! 秒杀业务 在电商领域,存在着典型的秒杀业务场景,那何谓秒杀场景呢。简单的来说就是一件商品的购买人数远远大于这件商品的库存,而且这件商品在很短的时间内就会被抢购一空。比如每年的618、双11大促,小米新品促销等业务场景,就是典型的秒杀业务场景。 秒杀业务最大的特点就是瞬时并发流量高,在电商系统中,库存数量往往会远远小于并发流量,比如:天猫的秒杀活动,可能库存只有几百、几千件,而瞬间涌入的抢购并发流量可能会达到几十到几百万。 所以,我们可以将秒杀系统的业务特点总结如下。 (1)限时、限量、限价 在规定的时间内进行;秒杀活动中商品的数量有限;商品的价格会远远低于原来的价格,也就是说,在秒杀活动中,商品会以远远低于原来的价格出售。 例如,秒杀活动的时间仅限于某天上午10点到10点半,商品数量只有10万件,售完为止,而且商品的价格非常低,例如:1元购等业务场景。 限时、限量和限价可以单独存在,也可以组合存在。 (2)活动预热 需要提前配置活动;活动还未开始时,用户可以查看活动的相关信息

Redis 是如何处理已过期元素的?[云图智联]

不打扰是莪最后的温柔 提交于 2020-10-03 13:21:11
1 面试题 Redis 如何处理已过期的元素? 2 涉及知识点 此问题涉及以下知识点: 过期删除策略有哪些? 这些过期策略有哪些优缺点? Redis 使用的是什么过期策略? Redis 是如何优化和执行过期策略的? 3 答案 常见的过期策略: 定时删除 惰性删除 定期删除 1)定时删除 在设置键值过期时间时,创建一个定时事件,当过期时间到达时,由事件处理器自动执行键的删除操作。 ① 优点 保证内存可以被尽快的释放 ② 缺点 在 Redis 高负载的情况下或有大量过期键需要同时处理时,会造成 Redis 服务器卡顿,影响主业务执行。 2)惰性删除 不主动删除过期键,每次从数据库获取键值时判断是否过期,如果过期则删除键值,并返回 null。 ① 优点 因为每次访问时,才会判断过期键,所以此策略只会使用很少的系统资源。 ② 缺点 系统占用空间删除不及时,导致空间利用率降低,造成了一定的空间浪费。 ③ Redis 源码解析 惰性删除的源码位于 src/db.c 文件的 expireIfNeeded 方法中,源码如下: int expireIfNeeded(redisDb *db, robj *key) { // 判断键是否过期 if (!keyIsExpired(db,key)) return 0; if (server.masterhost != NULL) return 1; /*