文档章节

Lua Web快速开发指南(6) - Cache、DB介绍

水果糖的小铺子
 水果糖的小铺子
发布于 06/16 01:05
字数 2383
阅读 42
收藏 2

"数据库"与"缓存"的基本概念

数据库与缓存是服务端开发人员的必学知识点.

数据库

"数据库"是一种信息记录、存取的虚拟标记地点的集合统称. 比如现实生活中, 我们经常会用到文件柜、书桌等等数据存取容器.

在对容器进行数据存取的时候, 我们会为每一层打上一个标签表示一种分类项. 而这种在数据库中划分子分类形成了的概念. 这就是我们通常所说的结构化数据库.

由于通常数据表之间可能会存在依赖关系, 某一(或者多)层通常可能会用于同一种用途. 这种用途将一层划分为索引表, 二层划分为分类表, 三层划分为数据表.

实现这种功能与依赖关系的数据库, 我们称之为: 关系型数据库. 它可以定义一套规范并且建立数据存取模型, 这样方便维护一整套结构化的数据信息.

每当我们需要对数据进行结构化操作(查询、增加、删除、修改)的时候, 需要在计算机中用一种通俗易懂的语言表达方式来进行助记. 这种结构化查询语言称之为SQL.

缓存

我们通常将数据存储完毕后, 能通过指定或特定的一(多)种方式对数据进行操作. 在项目开发的初期, 这并没有太大的问题.

但是随着数据量的不断增大, 在数据库的内存中已经放不下这么多数据. 我们的数据逐渐无法被加载到内存中: 只会在使用的时候才会进行(随机)读取. 而这会加大磁盘I/O.

我们知道通常磁盘的读写速度基本上会比内存读写慢几个数量级(即使是SSD), 大量请求可能瞬间将磁盘IO占满并出现数据库的CPU利用率低、内存频繁进行修改/置换等问题.

为了解决这些问题, 出现了很多解决方案: 读、写分离、分表分库等等. 虽然有了这些方案, 但是也同样回引来新的问题: 主从同步、分布式事务等问题.

"缓存"则是近十年兴起的概念, 它的本质是一份数据结构化存储在内存中的副本. 高级的缓存我们也可以将其称之为内存数据库NOSQL(非关系型)数据库.

"缓存"也是一种"另类"解决数据库问题点一种手段! 它通过丰富的数据结构扩展了数据模型的组合能力, 通过简单的使用方法与高效的连接方式提供更好数据操作方式.

"缓存"将查询、更新较为频繁的数据组成一个集合加载进内存中, 较少使用的数据序列化到磁盘内部. 高效利用内存的同时, 根据变化的情况合理更新、删除缓存.

这样的方式配合数据库都读、写分离与数据分区将数据合理的从一个数据集副本分散到多个数据集副本, 有效的减少性能问题点产生并且提升了整个业务系统的横向扩展能.

DB库

DB库是cf框架封装自MySQL 4.1协议实现的客户端连接库, 提供MySQL断线重连、SQL重试、连接池等高级特性.

Cache

Cache库是cf封装自Redis 2.0协议实现的客户端连接库, 提供Redis断线重连、命令重试、连接池等高级特性.

API学习

1. DB API

在使用下面的API之前, 请先确保已经导入库: local DB = require "DB".

1.1 DB:new(opts)

opts表的参数决定如何连接到MySQL, 表属性如下:

host - MySQL主机名或IP地址(string类型).

port - MySQL端口号(int类型).

charset - MySQL字符集设置.

database - MySQL库的名称.

username - MySQL用户账户(string类型).

password - MySQL用户密码(string类型).

max - MySQL的最大连接池大小(int类型).

这个方法返回一个新创建db对象

1.2 DB:connect()

开始连接MySQL. 连接成功返回True, 否则将会持续进行连接并且输出连接失败原因的日志.

1.3 DB:query(SQL)

数据库查询语句调用方法, SQL为string类型的的一个标准SQL语句.

返回值为ret与err. 查询成功ret为一个结果集数组, 在发生错误时未nil, err为错误信息.

2. Cache API

在使用下面的API之前, 请先确保已经导入库: local Cache = require "Cache".

2.1 Cache:new(opts)

opts表的参数决定如何连接到MySQL, 表属性如下:

host - Redis主机名或IP地址(string类型).

port - Redis主机端口号(int类型).

auth - Redis主机设置的密码, 默认为:nil.

db - Redis的数据库设置.

max = 最大连接池大小(int类型).

此方法返回一个新创建的Cache对象.

2.2 Cache:connect()

开始连接Redis. 连接成功返回True, 否则将会持续进行连接并且输出连接失败原因的日志.

2.3 Cache:API(...)

Cache支持大部分的redis API, 目前测试过多API在script/test_Cache.lua文件内部都有展示.

DB库的操作流程

DB库的操作与使用流程非常简单, 其目标是简化开发人员在业务编写过程中的使用难点.

创建数据库与数据表

启动一个MySQL实例并且初始化完毕, 具体安装与初始化方法根据平台不同而不同, 这不再本文讲解范围内.

然后我们使用默认的root用户并且root账户、密码设置完毕. 这里为了演示方便, 我们将root密码设置为: 123456789.

创建一个叫cf_mall的数据库字符集编码都设为utf-8. 并且在cf_mall数据库中创建一个叫做cf_users的表, 如下所示:

# 创建`cf_mall`数据库
CREATE DATABASE IF NOT EXISTS `cf_mall` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

# 创建`cf_users`用户表
CREATE TABLE IF NOT EXISTS `cf_mall`.`cf_users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`age` tinyint(3) unsigned NOT NULL COMMENT '用户年龄',
`name` varchar(255) NOT NULL COMMENT '用户名',
`username` varchar(255) NOT NULL COMMENT '用户账户',
`password` varchar(255) NOT NULL COMMENT '用户密码',
`email` varchar(255) NOT NULL DEFAULT '' COMMENT '用户邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

以上数据库创建语句可以在一些MySQL GUI工具中直接运行.

测试DB库的API写入数据

现在, 让我们利用上面学到的API尝试将作者的信息写入进去. 同时为了避免密码原文显示, 我们需要使用crypt库的base64方法将密码进行编码.

local crypt = require "crypt"
local DB = require "DB"
local db = DB:new {
	host = "localhost",
	port = 3306,
	username = 'root',
	password = 123456789,
	database = "cf_mall",
	charset = "utf8"
}

db:connect()

db:query(string.format([[
	INSERT INTO `cf_mall`.`cf_users`
		(`name`, `age`, `username`, `password`, `email`)
	VALUE
		('%s', '%s', '%s', '%s', '%s')
	]],
	'水果糖的小铺子', '29', 'candymi', crypt.base64encode('123456789'), '869646063@qq.com')
)
local ret, err = db:query("SELECT * FROM `cf_mall`.`cf_users` WHERE `name` = '水果糖的小铺子'")
if not ret then
	return print(ret, err)
end
return print('name:', ret[1].name, 'password:', ret[1].password, 'email:', ret[1].email)

检查问题

最后我们检查数据库内是否已经写入了我们需要存储的数据. 如果使用的SQL有语法错误导致写入失败, 请使用print检查db:query操作否出现错误.

同时我们在console控制台上可以检查是否输出了我们刚才写入到cf_users的信息.

Cache库的操作流程

Cache库拥有非常简单的使用方法, 几乎能运行所有Redis已提供的命令. 并且协议是二进制安全的(binary safe).

启动一个Redis实例

启动并运行一个redis实例. 具体安装与运行方法根据平台不同而不同, 这不再本文讲解范围内.

并且这里为了演示示例简单, 我们将不设置任何auth并且使用默认的db.

将数据加载到Redis

我们将列出目前已知的一些知名大众化语言, 然后将其写入到Redis中.

local Cache = require "Cache"

local cache = Cache:new {
	host = 'localhost',
	port = 6379,
}

cache:connect()
local ok, msg = cache:rpush("languages", "C", "C++", "Java", "Golang", "Ruby", "Python", "PHP", "Lua")
if not ok then
  return print(ok, msg)
end
print("当前language的总数为:", msg)

问题排查

最后, 让我们用Redis自带的命令行工具查看是否真实写入了数据.

[candy@MacBookPro:~] $ redis-cli
127.0.0.1:6379> lrange languages 0 -1
1) "C"
2) "C++"
3) "Java"
4) "Golang"
5) "Ruby"
6) "Python"
7) "PHP"
8) "Lua"
127.0.0.1:6379>

可以看到数据已经写入进去. 如果发送参数错误与语法发生错误, msg将会是您排查错误的有效信息.

更多

更多API详情请参考MySQL、Redis的使用文档并且在实际开发中进行体验.

继续学习

下一章节我们将继续学习如何利用httpc库请求第三方接口

© 著作权归作者所有

水果糖的小铺子
粉丝 23
博文 153
码字总数 73315
作品 1
广州
程序员
私信 提问
Lua Web快速开发指南(2) - cf的运行机制简介与基于httpd库的开发环境搭建

从本章开始假设大家都熟悉lua语法. 运行流程 在上一章节学会了如何安装cf后, 本章节就会介绍cf到运行机制与httpd的server搭建! cf是一个非常典型的基于协程的事件驱动开发框架在封装成API后,...

水果糖的小铺子
06/14
0
0
Lua Web快速开发指南(1) - 初识cf框架

cf是什么? cf全称为: CoreFramework. 一个基于Reactor事件驱动与协程的lua高性能网络框架, 目前主要面向HTTP Application开发. cf内部主要实现了包括HTTP与HTTP Over Websoket协议的Server,...

水果糖的小铺子
06/14
0
0
利用LUA协程实现FUTURE模式

1. Future模式: 参见http://www.cnblogs.com/zhiranok/archive/2011/03/26/Future_Pattern.html 使用future的好处是即利用了异步的并行能力,又保证主逻辑串行执行,保持简单。 2. Lua 协程...

晨曦之光
2012/06/07
685
0
手把手教你在Flutter项目优雅的使用ORM数据库

Flutter ORM数据库介绍 Flutter现在开发上最大的槽点可能就是数据库使用了,Flutter现在只提供了sqflite插件,这表明开发者手动写sql代码,建表、建索引、transation、db线程控制等等繁琐的事...

williamwen1986
01/22
0
0
《亿级流量网站架构核心技术》目录一览

举报   在2011年年底的时候笔者就曾规划写一本Spring的书,但是因为是Spring入门类型的书,框架的内容更新太快,觉得还是写博客好一些,因此就把写完的书稿放到了博客(jinnianshilongnia...

jinjiang2009
2017/03/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

拥有有趣灵魂的程序员们,程序员访谈(一)

点击上方关注我们,让小care关爱你! 程序员群体一直都是低调多金的代表,而近段时间以来,程序员在网络上除了高薪之外,总是会和屌丝、苦逼、格子衫、没情趣...联系在一起。黑程序员的段子也...

ITCare
今天
23
0
Linux输入法fcitx的安装问题

Fcitx 总共要安装的包如下 fcitxfcitx-binfcitx-config-commonfcitx-config-gtk | fcitx-config-gtk2fcitx-datafcitx-frontend-allfcitx-frontend-gtk2fcitx-frontend-gtk3......

CHONGCHEN
今天
13
0
网络基础

前言: 最近整理一些以前的学习笔记(有部分缺失,会有些乱,日后再补)。 过去都是存储在本地,此次传到网络留待备用。 计算机网络的功能: 1.数据通信; 2.资源共享; 3.增加数据可靠性; 4....

迷失De挣扎
今天
13
0
spring boot升级到spring cloud

1、先升级spring boot 版本到2.1.3 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.3.RELEAS......

moon888
今天
26
0
从蓝鲸视角谈DevOps

DevOps源于Development和Operations的组合 常见的定义 DevOps是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变...

嘉为科技
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部