翻译 《An Empirical Evaluation of In
工作中对于MVCC接触的已经比较多了,但是依然对MVCC的实现细节以及设计思路没有比较清晰的认知,因此在这里翻译一篇关于内存介质的MVCC的整体介绍,也作为笔记。
摘要
MVCC(Multi-version concurrency control多版本并发控制)是现代数据库管理系统最流行的事务管理方式。尽管早在19世纪70年代就已经发明了MVCC技术,但它仍然被近十年主流的数据库系统广泛使用。MVCC通过维护多个版本的数据,一定程度上,在不影响事务的可串行性的同时提升了数据库的并发度。然而在多核的内存操作环境下,拓展MVCC并不是一件容易的事情:当有大量线程在并行运行时,线程间同步的开销可能足以抵消MVCC带来的并发优化。
为了了解现代硬件环境下MVCC机制如何处理事务,我们从四个主要维度进行了广泛的调研:并发控制协议、版本存储、垃圾回收以及索引管理。我们用了以上技术的最先进方法实现了内存数据库,并且用OLTP的负载来进行评测。我们分析出了各种设计上的取舍导致的关键瓶颈。
1. 简介
多核的出现带来了计算机架构的进化,内存数据库系统在不牺牲可串行性的前提下,实现了高效的事务管理 ...
lua
介绍
Lua 是一个小巧的脚本语言。openresty采用的是LuaJIT 2 ,而不是标准的lua。
解释下什么是jit
LuaJIT 的运行时环境包括一个用手写汇编实现的 Lua 解释器和一个可以直接生成机器代码的 JIT 编译器。
Lua 代码在被执行之前总是会先被 lfn 成 LuaJIT 自己定义的字节码(Byte Code)。关于 LuaJIT 字节码的文档,可以参见:http://wiki.luajit.org/Bytecode-2.0(这个文档描述的是 LuaJIT 2.0 的字节码,不过 2.1 里面的变化并不算太大)。
一开始的时候,Lua 字节码总是被 LuaJIT 的解释器解释执行。LuaJIT 的解释器会在执行字节码时同时记录一些运行时的统计信息,比如每个 Lua 函数调用入口的实际运行次数,还有每个 Lua 循环的实际执行次数。当这些次数超过某个预设的阈值时,便认为对应的 Lua 函数入口或者对应的 Lua 循环足够的“热”,这时便会触发 JIT 编译器开始工作。
JIT 编译器会从热函数的入口或者热循环的某个位置开始尝试编译对应的 Lua 代码路径。 ...
Redis Lua脚本大学教程
前面我们已经把Redis Lua相关的基础都介绍过了,如果你可以编写一些简单的Lua脚本,恭喜你已经可以从Lua中学毕业了。
在大学课程中,我们主要学习Lua脚本调试和Redis中Lua执行原理两部分内容两部分。
Lua脚本调试Redis从3.2版本开始支持Lua脚本调试,调试器的名字叫做LDB。它有一些重要的特性:
它使用的是服务器-客户端模式,所以是远程调试。Redis服务器就是调试服务器,默认的客户端是redis-cli。也可以开发遵循服务器协议的其他客户端。
默认情况下,每个debugging session都是一个新的session。也就是说在调试的过程中,服务器不会被阻塞。仍然可以被其他客户端使用或开启新的session。同时也意味着在调试过程中所有的修改在结束时都会回滚。
如果需要,可以把debugging模式调成同步,这样就可以保留对数据集的更改。在这种模式下,调试时服务器会处于阻塞状态。
支持步进式执行
支持静态和动态断点
支持从脚本中向调试控制台打印调试日志
检查Lua变量
追踪Redis命令的执行
很好的支持打印Redis和Lua的值
无限循环和长执行检测,模拟 ...
LeetCode 150. Evaluate Reverse Polish Notation
题目描述根据逆波兰表示法(后缀表达式),求表达式的值。
有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
tag基本计算器题 栈
样例1234567891011121314151617181920212223输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]输出: 22解释: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5= ((10 * (6 / (12 * -11))) + 17) + 5= ((10 * (6 / -132)) + 17) + 5= ((10 * 0) + 17) ...
Lua 汉字拼音首字母提取
最近项目上有个需求,需要将一些联系人数据按照拼音首字母排序。google 了一番,竟然没有找到一个合适的 Lua 解决方案。倒是找到一个 lua-pinyin,粗略翻了下源码发现其是将所有的中文返回全部完整的拼音,原理是将所有汉字对应拼音创建好数据字典,载入 Lua,之后查询这个字典,返回对应的拼音。但是这对于我这个需求来说显然是太臃肿了,我只需要返回首字母就可以了,却载入一个巨大的字典,感觉有点浪费内存,尤其是在 OR 对于 Lua 的内存是有限制的情况下。
为此自己造了个轮子:lua-resty-pyf,感兴趣的同学可以去 github 搜下。这里我来说下原理。
如果单从排序的角度来看,我们其实完全可以利用 GBK 中文的顺序编码来解决,而且 GBK 是固定字节编码,即:两个字节(一个区码和一个位码)。我们先计算出汉字对应的 GBK 码点,之后按照码点排序就实现了首字母的排序。
如果需要提取出首字母用于检索,我们就必须建立一个映射关系,把所有汉字对应的首字母全部映射进去。好在已经有个老外做了这部分的工作,这里我用 ffi 简单封装了下,暴露出了 lua 的接口。
需要注意的是我们这 ...
浅谈 ngx_lua 在 UPYUN 的应用
ngx_lua 是一个 NGINX 的第三方扩展模块,它能够将 Lua 代码嵌入到 NGINX 中来执行。
UPYUN CDN 大量使用了 NGINX 作为反向代理服务器,其中绝大部分的业务逻辑已经由 Lua 来驱动了。
这个主题之前在 OSC 源创会 2014 北京站 和 SegmentFault D-Day 2015 南京站 有做过简单分享,Slide 在这里:《Using ngx_lua in UPYUN》,大家有兴趣可以先看下,更多资料也可以在 Github 上获取。不过两次分享都由于个人时间安排上的不足,对 Keynote 后半部分偏实践的内容并没有做过多地展开,未免有些遗憾,因此,本文作为一个补充将尝试以文字的形式来谈谈这块内容 :-)
ngx_lua 和 Openresty
Openresty 是一套基于 NGINX 核心的相对完整的 Web 应用开发框架,包含了 ngx_lua 在内的众多第三方优秀的 NGINX C 模块,同时也集成了一系列常用的 lua-resty-* 类库,例如 redis, mysql 等,特别地,Openresty 依赖的 NGINX 核心和 ...
Lua标准库
lua标准库之table库
table库的概念是由一些操作table的辅助函数组成
作用一:对lua中的表的大小给出一个合理的解释,如getn,#table等
作用二:提供一些插入删除元素以及元素排序的函数,如insert,remove等
Lua5.1中字符串库的所有函数如下表:先定义一张表 t = {1,2,3}
函数
描述
示例
结果
#
取表长
#t
3
getn
取表长
Table.getn(t)
3
setn
设置table中的元素个数
Table.setn(t,4)
4
maxn
返回表中最大key
Table.maxn(t)
3
concat
表连接
insert
往表的指定位置插入key
table.insert(t,4)
{1,2,3,4}
remove
删除表的指定位
table.remove(table,3)
{1,2,3}
sort
给表排序,默认升序
table.sort(t)
{1,2,3}
取表长两种方法#和getn
#:返回表的长度(只返回变量是数字的和当nil在非最后一个元素的位置)
table.ge ...
lua类机制
lua类机制的简易实现12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576local _class={} function (super) local class_type={} class_type.ctor=false class_type.super=super class_type.new=function(...) local obj={} do local create create = function(c,...) if c.super then create(c.super,...) end if c.ctor then c.ctor(obj,...) end end create(class_type,...) end setmetatabl ...
cocos2dx lua 闭包(匿名函数)入门实战
本文首先通过具体的例子讲解了Lua中闭包的概念,然后总结了闭包的应用场合,最后探讨了Lua中闭包的实现原理。
闭包的概念
在Lua中,闭包(closure)是由一个函数和该函数会访问到的非局部变量(或者是upvalue)组成的,其中非局部变量(non-local variable)是指不是在局部作用范围内定义的一个变量,但同时又不是一个全局变量,主要应用在嵌套函数和匿名函数里,因此若一个闭包没有会访问的非局部变量,那么它就是通常说的函数。也就是说,在Lua中,函数是闭包一种特殊情况。
不知道c++的lambda和lua的闭包是谁先谁后,不过就我来说,是先学了c++,最近才接触到现代lua。因此把一切向c++看齐,会不自觉地把一切和c++做对比。
就闭包来说,不就是c++的lambda嘛!
前面所说的upvalue,也就是一开始按引用捕获,在变量退出生命期时,拷贝到Functor的成员变量里来,变成了按值捕获。这算是解释性语言特有的灵活性吧,变量可以在运行时按解释器的便利来移动位置,而不必像苦哈哈的编译性语言,一旦决定好位置,就无法移动了。
在Lua的C API中,所有关于Lu ...
Redis 集群 Lua 操作
redis 集群的单键操作,基本跟单机版一样,没有太大的区别redis集群的操作相对麻烦一点,由于slot的存在,同一组key可能会被分派到不同的slot中,这会导致lua在执行多键操作时遇到错误
需要使用redis 的hashtag来将一组类似的key分配到同一个slot中,方便lua操作
具体原理见redis hash tag
具体操作方式时对一组key,选取key中的某个部分,前后标记“{}” ,如:
helloredisone->hello{redis}one
helloredistwo->hello{redis}two
这样两个key由于相同的hash tag,会被分配到同一个slot中,这样lua操作就正常了