前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在云函数中使用真正serverless的kv数据

在云函数中使用真正serverless的kv数据

原创
作者头像
黄希彤
修改2022-04-29 12:05:34
9460
修改2022-04-29 12:05:34
举报
文章被收录于专栏:黄希彤的专栏黄希彤的专栏

上次在云函数里面整了一个嵌入式的SQL数据库以后爽的连云开发数据库都不想用了。不过有的时候还是需要用到kv存储,那能不能也serverless一把呢?level就是一个还不错的选择。打包一个层以后直接引用就可以了:

代码语言:javascript
复制
'use strict';
const { Level } = require('level')
// Create a database
const db = new Level('/tmp/example', { valueEncoding: 'json' })

exports.main_handler = async (event, context) => {

	var n  = 10000,d=Date.now();
	// Add an entry with key 'a' and value 1
	for(var i=0;i<n;i++){
		await db.put(Math.random().toString(16).substring(2), Math.random())
	}
	console.log("插入"+n+"个记录耗时"+(Date.now()-d)+"毫秒")


	// Add multiple entries
	let batch=[];
	for(var i=0;i<n;i++){
		batch.push({type:'put',key:Math.random().toString(16).substring(9), value:Math.random()})
	}
	d=Date.now();
	await db.batch(batch)
	console.log("批量插入"+n+"个记录耗时"+(Date.now()-d)+"毫秒")

	// Get value of key 'a': 1
	d=Date.now();
	for(var i=0;i<n;i++){
		try{
			let v = await db.get(Math.random().toString(16).substring(9));
			if(v) console.log("got value:"+v)	
		}catch(e){
			if(e.code != "LEVEL_NOT_FOUND")
			console.log(e)
		}
	}
	console.log("查询"+n+"个记录耗时"+(Date.now()-d)+"毫秒")

    return "all done"
};

(纯测试,保存路径用了/tmp/ 实际使用的时候应该挂上CFS)

这个level似乎是纯JS实现,比起通过node-gyp用C实现了关键计算的sqlite,读写性能上并没有太大优势,不过多一个选择还是不错的。以后小应用就可以纯云函数实现小规模提供服务了,小并发的时候性能甚至可能比云数据库服务更好。规模上去的时候再更换存储方案大部分主要的逻辑也能沿用。

facebook的rocksDB 是另一个选择。它和sqlite一样使用了node-gyp本地构建的方式,让人期待了一下它会不会有更好的性能表现。依赖node-gyp的层直接在mac上打包上传到linux服务器上是用不了的,因此使用了docker的linux + nodejs环境环境搭建

代码语言:javascript
复制
echo "cd /usr/src;npm install rocksdb --save">tmp.sh
chmod +x tmp.sh
docker run --rm -v "$PWD":/usr/src node:16 /usr/src/tmp.sh
zip -r rocksdb.zip node_modules
rm -rf node_modules tmp.sh package.json package-lock.json

这样就得到了一个layer,超过10M无法上传上来,需要的自己生成一下。

按照leveldown的api运行测试了一下:

代码语言:javascript
复制
'use strict';
const rocksdb = require('rocksdb')

// Create a database

const db =  new rocksdb("/tmp/rocksdb")
async function openDB(){
	return new Promise(res=>{
		db.open({createIfMissing:true},()=>{
			console.log("db opened");
			res();
		})
	})
}
async function closeDB(){
	return new Promise(res=>{
		db.close(function (err) {
			console.log("db closed")
			res()
		})
	})
}
exports.main_handler = async (event, context) => {
	await openDB();
	var n  = 200,d=Date.now();
	for(var i=0;i<n;i++){
		db.put(Math.random().toString(16).substring(2), Math.random(),{'sync':true},()=>{})
	}
	console.log("同步插入"+n+"个记录耗时"+(Date.now()-d)+"毫秒(同步插入太多DB就崩溃了,并且会干扰后面的异步操作,不推荐)");
	await closeDB().then(openDB);//重新打开一次数据库来消除同步操作的干扰
	d=Date.now();
	for(var i=0;i<n;i++){
		await new Promise(res=>{
			db.put(Math.random().toString(16).substring(2), Math.random(),()=>{res()})
		})
	}
	console.log("异步步插入"+n+"个记录耗时"+(Date.now()-d)+"毫秒(会受到前面同步插入的干扰,需要重新打开一次DB来测试)")

	n=10000
	let batch = db.batch();
	for(var i=0;i<n;i++){
		batch.put(Math.random().toString(16).substring(9),Math.random())
	}
	d=Date.now();
	await new Promise(res=>{batch.write(res)})
	console.log("批量插入"+n+"个记录耗时"+(Date.now()-d)+"毫秒")

	d=Date.now();
	for(var i=0;i<n;i++){
		let v = await new Promise(res=>{db.get(Math.random().toString(16).substring(9),(err,value)=>{
			if(err == null)
				res(value)
			else
				res()
		})})
		if(v) console.log("got value "+v)
	}
	console.log("查询"+n+"个记录耗时"+(Date.now()-d)+"毫秒")

	await closeDB()
	return "all done"

};

除了性能不咋地,数据量上去一点还很容易挂掉,可能使用的姿势还不大对?

还有一些更简单的jsonDB类小玩具,比如lowdb(这个是pure ESM 包,引用的时候要注意一下),jsondbsimple-json-db等,使用简单又各有特色,小数据量玩玩应该都不错。

本来还有一个选择的,BerkeleyDB据说也很香,但是尝试打包一个layer的时候发现接近120M,无法压缩到layer要求的50M以内

代码语言:javascript
复制
echo "cd /usr/src">tmp.sh
echo "npm init -y ">>tmp.sh
echo "npm install berkeleydb --save">>tmp.sh
chmod +x tmp.sh
docker run --rm -v "$PWD":/usr/src node:11 /usr/src/tmp.sh
zip -q -r berkeleydb_node11.zip node_modules
rm -rf node_modules package-lock.json package.json tmp.sh

将来有更多需求的时候再尝试用其他的方式把它打包进来用用吧。

最后,还是觉得就嵌入式数据库而言,sqlite是比较香的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档