最近有幸参与了腾讯云举办的 腾讯云 TDSQL-C 产品体验活动。在这个过程中,通过了解 TDSQL-C 的产品和实践,让我受益非浅,原来数据库还能这么玩! 也让我真正体会到了降本增效这个词的意义。
在看到活动的介绍和微信群的讲解后,我马不停蹄地开始了自己摸索。首先是跟着群里小助手发的实验手册,体验了一下整个产品的业务流程。
随后又查看官方的产品文档,文档非常的简洁明了,然后根据这些资料开始了我的第一个 TDSQL-C 程序,基于 TDSQL-C 数据库构建了一个基于 Vue 的问卷调查系统,亲身体验了 TDSQL-C 带来的高性能、弹性可靠服务,整个过程十分丝滑。
下面就来整理,分享一下我的操作和感悟,希望能够帮助到其他同学。
传统数据库为什么被云数据库替代?
关于 TDSQL-C 的出现,我觉得需要先从云数据库开始了解,传统的本地数据库部署需要企业自己购买、维护硬件设备和管理数据库软件,这对于资源有限的中小企业来说可能是一项昂贵和繁琐的任务。同时,传统数据库在面对大规模的数据处理和高并发访问时可能会遇到性能瓶颈和可用性问题。云数据库的出现解决了这些问题。它将数据库部署在云平台上,并提供弹性的计算和存储资源,使用户能够根据实际需求按需扩展数据库的容量和性能。云数据库还提供高可用性和可靠性,通过数据备份、冗余存储和容灾机制来保护数据的安全和可恢复性。此外,云数据库还提供了便捷的管理和监控工具,简化了数据库的操作和维护过程。
serverless数据库带来了什么好处?
而云 Serverless 数据库的出现则是为了进一步提供更高的灵活性和经济效益。传统的数据库需要预先配置和维护一定数量的计算资源,而这些资源在闲置时仍然需要付费。而 Serverless 数据库采用按需付费的模式,它根据实际的计算和存储资源使用量来计费,无需预先配置资源。这使得用户可以根据实际需求动态地扩展和缩减数据库的资源,避免了资源浪费和额外的成本支出。Serverless 数据库还可以自动管理和优化资源,用户只需专注于应用开发,而无需关注底层基础设施的管理。
而 TDSQL-C 是腾讯云自研的新一代云原生关系型数据库。融合了传统数据库、云计算与新硬件技术的优势,100%兼容 MySQL,为用户提供极致弹性、高性能、高可用、高可靠、安全的数据库服务。实现超百万 QPS 的高吞吐、PB 级海量分布式智能存储、Serverless 秒级伸缩,助力企业加速完成数字化转型。
Serverless 服务是腾讯云自研的新一代云原生关系型数据库 TDSQL-C MySQL 版的无服务器架构版,是全 Serverless 架构的云原生数据库。Serverless 服务支持按实际计算和存储资源使用量收取费用,不用不付费,将腾讯云云原生技术普惠用户。
总的来说,云数据库和云 Serverless 数据库的产生是为了满足不同规模和需求的用户对于数据存储和处理的需求,并提供更灵活、可扩展和经济高效的解决方案。
TDSQL-C MySQL 版基于 Cloud Native 设计理念,既融合了商业数据库稳定可靠、高性能、可扩展的特征,又具有开源云数据库简单开放、高效迭代的优势。
我们来理解一下这段描述, Cloud Native 设计理念是什么?
Cloud Native 设计理念是一种在云计算环境下进行应用开发和部署的方法论和思维方式,目标是将应用程序和基础设施解耦,使得应用程序能够更好地适应云环境的动态性和弹性,并提供更好的可伸缩性、可靠性和可管理性。它能够帮助开发者更快速、高效地构建和交付应用程序,并更好地应对日益复杂和变化的业务需求。
基于这个设计方式,所以 TDSQL-C MySQL 版可以为为用户提供具备超高弹性、高性能、海量存储、安全可靠的数据库服务,以可帮助企业轻松应对诸如商品订单等高频交易、伴随流量洪峰的快速增长业务、游戏业务、历史订单等大数据量低频查询、金融数据安全相关、开发测试、成本敏感等的业务场景。
我找到了一些关于我们在选择底层组件时候需要关注的一些特点,凭什么 TDSQL-C 值得我们选择呢?
TDSQL-C MySQL 版将开源数据库的计算和存储分离,存储构建在腾讯云分布式云存储服务之上,计算层全面兼容开源数据库引擎 MySQL 5.7、8.0,业务无需改造即可平滑迁移。
单节点百万 QPS 的超高性能,可以满足高并发高性能的场景,保证关键业务的连续性,并可进一步提供读写分离以及读写扩展性。
最高支持 PB 级的海量存储,为用户免去面对海量的数据时频繁分库分表的繁琐操作,同时支持数据压缩,在海量数据检索和写入性能上进行了大量优化。
计算节点实现了无状态,支持秒级的故障切换和恢复,即便计算节点所在的物理机宕机也可以在一分钟之内恢复。
集群支持安全组和 VPC 网络隔离。自动维护数据和备份的多个副本,保障数据安全可靠,可靠性达99.9999999%。
计算节点可根据业务需要快速升降配,秒级完成扩容,结合弹性存储,实现计算资源的成本最优。
计算节点可根据业务需要快速添加只读节点,一个集群支持秒级添加或删除1个 - 15个只读节点,快速应对业务峰值和变化场景。
基于数据多版本的秒级快照备份对用户的数据进行连续备份保护,免去主从架构备份回档数据的同步和搬迁,最高以GB/秒的速度极速并行回档,保证业务数据迅速恢复。
Serverless 是腾讯自研云原生数据库 TDSQL-C MySQL 版的无服务器架构版,自动扩缩容,仅按照实际使用量计费,不用不计费,轻松应对业务数据量动态变化和持续增长。
TDSQL-C MySQL版广泛适用于多个行业和应用场景,具备以下条件和优势:
互联网移动应用:
游戏应用:
电商、直播、教育行业:
金融、保险企业:
这些条件和优势使TDSQL-C MySQL版适用于各种业务场景,包括高频交易、快速增长业务、大数据量低频查询、金融数据安全、开发测试和成本敏感场景。
我这次准备使用 TDSQL-C Serverless MySQL 快速搭建一个爬虫应用,这里我们打算使用 Python来实现,来体验 云原生数据库 TDSQL-C 给我们带来的优势。
如下为最项目代码如下:
让我们开始构建吧!!!
一直下一步购买后就能在TDSQL-C集群列表中看见
CREATE TABLE `cate` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `type` varchar(255) DEFAULT NULL COMMENT 'kg | kw | wyy | qq', `cate` varchar(255) DEFAULT NULL COMMENT '分类', `primary_key` bigint(255) DEFAULT NULL COMMENT '平台主键', `create_date` datetime DEFAULT NULL, `update_date` datetime DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `u` (`type`,`primary_key`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; CREATE TABLE `playlist` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL COMMENT '标题', `desc` longtext COMMENT '描述', `cate` varchar(255) DEFAULT NULL COMMENT '类型', `cate_id` varchar(255) DEFAULT NULL, `is_own` tinyint(255) DEFAULT '1' COMMENT '1 第三方创建的 2自己创建的', `primary_key` varchar(255) DEFAULT NULL COMMENT '第三方歌单主键', `key_type` char(10) DEFAULT NULL COMMENT 'qq | kg | wyy | kw ', `thumb_img` longtext COMMENT '封面', `tag` text COMMENT '标签 ,', `tag_id` text COMMENT '标签id ,拆分', `author` varchar(255) DEFAULT NULL COMMENT '作者', `author_id` bigint(255) DEFAULT NULL COMMENT '作者id', `collect_num` bigint(20) DEFAULT '0' COMMENT '收藏数量', `share_num` bigint(20) DEFAULT '0' COMMENT '分享数量', `comment_num` bigint(255) DEFAULT '0' COMMENT '评论数量', `play_num` bigint(20) DEFAULT '0' COMMENT '歌单播放次数', `song_num` bigint(20) DEFAULT '0' COMMENT '歌单歌曲数量', `platform_create_date` datetime DEFAULT NULL COMMENT '第三方歌单创建时间', `create_date` datetime DEFAULT NULL, `update_date` datetime DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
一个是分类表,用于存储歌单的分类信息,然后通过分类去获取歌单列表
另一个是歌单表,用于存储爬取的歌单数据
这里我采用了 feapder 这个轻量级框架
pip3 install feapder[all]
feapder create -p QQSpider
# # MYSQL MYSQL_IP = "gz-xxxxxx" MYSQL_PORT = 28671 MYSQL_DB = "questionnaire" MYSQL_USER_NAME = "root" MYSQL_USER_PASS = "123456" # # REDIS # # ip:port 多个可写为列表或者逗号隔开 如 ip1:port1,ip2:port2 或 ["ip1:port1", "ip2:port2"] REDISDB_IP_PORTS = "x" REDISDB_USER_PASS = "x" REDISDB_DB = 7
feapder~=1.7.7 pycryptodome Flask~=2.2.2 pillow~=9.2.0 requests-toolbelt requests~=2.27.1 apscheduler~=3.9.1 js2py~=0.71 urllib3~=1.26.11 pytz~=2022.1 gevent~=21.12.0
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
为了方便可以把这个 shell 写在项目的根目录
import feapder import urllib.parse from feapder import Request from items.cateItem import CateItem class CategorySpider(feapder.Spider): commonParams = { 'g_tk': 1124214810, 'loginUin': '0', 'hostUin': 0, 'inCharset': 'utf8', 'outCharset': 'utf-8', 'notice': 0, 'platform': 'yqq.json', 'needNewCode': 0, } apiHeader = { 'referer': 'https://c.y.qq.com/', 'host': 'c.y.qq.com' } domain = 'https://c.y.qq.com' def start_requests(self): url = "/splcloud/fcgi-bin/fcg_get_diss_tag_conf.fcg?" + self.getParams({ 'format': 'json', 'outCharset': 'utf-8', }) yield self.request(url, method="GET") def request(self, path, **kwargs): req = Request(self.domain + path, **kwargs) return self.downloadMidware(req) def downloadMidware(self, request): if request.url.startswith('https://y.qq.com/n/ryqq/playlist'): return request request.headers = self.apiHeader return request def getParams(self, params): data = params data.update(self.commonParams) return urllib.parse.urlencode(data) def validate(self, request, response): jsonData = response.json if jsonData['code'] != 0: raise Exception(jsonData['message']) return True def parse(self, request, response): jsonData = response.json for cate in jsonData['data']['categories']: cateName = cate['categoryGroupName'] for item in cate['items']: cateItem = CateItem() cateItem.primary_key = item['categoryId'] cateItem.title = item['categoryName'] cateItem.type = "qq" cateItem.cate = cateName yield cateItem if __name__ == "__main__": CategorySpider(redis_key="qq_category:spider").start()
这里我们还要配置一下 ORM,在itmes目录下创建 cateItem,用于映射数据库表,方便直接入库,不用编写原生SQL
from feapder import Item from feapder.utils import tools class CateItem(Item): """ This class was generated by feapder. command: feapder create -i spider_data. """ __unique_key__ = ["title", "cate", "type", 'primary_key'] # 指定去重的key为 title、url,最后的指纹为title与url值联合计算的md5 def __init__(self, *args, **kwargs): # self.id = None super().__init__(**kwargs) self.table_name = "cate" self.title = None self.cate = None self.primary_key = None self.type = None self.create_date = None self.update_date = None def pre_to_db(self): """ 入库前的处理 """ self.create_date = tools.format_time("刚刚") self.update_date = tools.format_time("刚刚")
可以看到数据已经全部入库了
同理,我们先建立一下歌单表的 ORM
from feapder import Item from feapder.utils import tools class PlaylistItem(Item): def __init__(self, *args, **kwargs): # self.id = None super().__init__(**kwargs) self.table_name = "playlist" self.title = None self.desc = None self.primary_key = None self.cate = None self.cate_id = None self.key_type = None self.thumb_img = None self.tag = None self.tag_id = None self.author = None self.author_id = None self.collect_num = None self.share_num = None self.comment_num = None self.play_num = None self.song_num = None self.platform_create_date = None self.create_date = None self.update_date = None def pre_to_db(self): """ 入库前的处理 """ self.create_date = tools.format_time("刚刚") self.update_date = tools.format_time("刚刚")
然后创建爬虫
import urllib.parse import feapder from feapder import Request from feapder.db.mysqldb import MysqlDB from items.playlistItem import PlaylistItem class PlayListSpider(feapder.Spider): commonParams = { 'g_tk': 1124214810, 'loginUin': '0', 'hostUin': 0, 'inCharset': 'utf8', 'outCharset': 'utf-8', 'notice': 0, 'platform': 'yqq.json', 'needNewCode': 0, } apiHeader = { 'referer': 'https://c.y.qq.com/', 'host': 'c.y.qq.com' } domain = 'https://c.y.qq.com' def start_requests(self): db = MysqlDB() cateList = db.find(sql="select * from cate where type = 'qq'", to_json=True) for cate in cateList: yield self.getPlaylistByCateId(cate['primary_key'], cate['title']) def getPlaylistByCateId(self, cateId, cateTitle, page=0, limit=50, sortId=5): sin = +page * +limit ein = +limit * (+page + 1) - 1 params = self.getParams({ 'format': 'json', 'outCharset': 'utf-8', 'picmid': 1, 'categoryId': cateId, 'sortId': sortId, 'sin': sin, 'ein': ein, }) url = "/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg?" + params return self.request(url, method="GET", page=page, limit=limit, cateId=cateId, cateTitle=cateTitle) def getParams(self, params): data = params data.update(self.commonParams) return urllib.parse.urlencode(data) # 构造请求 def request(self, path, **kwargs): req = Request(self.domain + path, **kwargs) return self.downloadMidware(req) # 构造请求头 def downloadMidware(self, request): if request.url.startswith('https://y.qq.com/n/ryqq/playlist'): return request request.headers = self.apiHeader return request def validate(self, request, response): jsonData = response.json if jsonData['code'] != 0: raise Exception(jsonData['message']) return True def parse(self, request, response): jsonData = response.json playlist = jsonData['data']['list'] for item in playlist: playlist = PlaylistItem() playlist.title = item.get('dissname') playlist.thumb_img = item.get('imgurl') playlist.create_date = item.get('createtime') playlist.primary_key = item.get('dissid') playlist.desc = item.get('introduction') playlist.play_num = item.get('listennum') playlist.cate = request.cateTitle yield playlist # 分页处理 if len(playlist) != 0: yield self.getPlaylistByCateId(request.cateId, request.cateTitle, request.page + 1, request.limit) # 通过分类id获取歌单列表 if __name__ == "__main__": PlayListSpider(redis_key="qq_playlist:spider").start()
运行爬虫后可以看到数据库的吞吐率很高,一会就有几千条数据了
在爬取的过程中,我一直担心数据库会成为应用的瓶颈,没想到最低配的 TDSQL-C 性能也是异常的强悍,期间通过自带的监控告警,也是很方便观察到秒级性能波动
然后 TDSQL-C 旁边还有个 数据库智能管家,这是一个非常利于我们在线运维的工具,他可以看到当前实例的:异常、性能趋势、实时会话、慢SQL分析、SQL优化、审计日志等等
他还可以为我们根据时间区间创建健康报告,让我们清晰地了解到数据库实例的健康状态,针对重要项目,我们可以设置定期报告,然后通过邮箱接收报告内容,从而减轻我们的运维负担
本次案例主要让大家对云原生数据库 TDSQL-C Serverless 有一个基本的认识,可以看到 TDSQL-C Serverless 与平时所使用的 Sql 语法差不多一致,基本上没有什么学习成本,开箱即用,可以快速上手,真正的无缝接入, 异常的丝滑!!
针对本次体验,我也总结了一些优点与遇到的一些问题,希望分享给大家,能给大家带来一些技术选型建议:
后面将这个默认值改大之后就再也没出现过了:
腾讯云TDSQL-C官方文档
feapder框架
上一篇:MySQL字符串转数字三种方式