惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LINUX DO - 最新话题
罗磊的独立博客
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
H
Hacker News: Front Page
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Hacker News
The Hacker News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
大猫的无限游戏
大猫的无限游戏
PCI Perspectives
PCI Perspectives
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Proofpoint News Feed
NISL@THU
NISL@THU
小众软件
小众软件
S
Security Affairs
腾讯CDC
人人都是产品经理
人人都是产品经理
C
Check Point Blog
The GitHub Blog
The GitHub Blog
有赞技术团队
有赞技术团队
Forbes - Security
Forbes - Security
Project Zero
Project Zero
G
Google Developers Blog
博客园 - 三生石上(FineUI控件)
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园_首页
Jina AI
Jina AI
The Cloudflare Blog
C
Cisco Blogs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
L
Lohrmann on Cybersecurity
Y
Y Combinator Blog
W
WeLiveSecurity
V
Visual Studio Blog
Scott Helme
Scott Helme
N
News | PayPal Newsroom
I
Intezer
C
CXSECURITY Database RSS Feed - CXSecurity.com
Attack and Defense Labs
Attack and Defense Labs
Spread Privacy
Spread Privacy
Webroot Blog
Webroot Blog
T
Threatpost
雷峰网
雷峰网
MongoDB | Blog
MongoDB | Blog
N
News and Events Feed by Topic

博客园 - 问天

开发笔记1: 范型 C#范型不会用,求助~ Web安全,以新浪微博“郭美美”蠕虫为例 介绍两个Python web框架:Django & Tornado 扯一下抽象 跟赵姐夫扯 webform的设计 MoSonic:对SubSonic的分布式存储、缓存改进尝试(3) MoSonic:对SubSonic的分布式存储、缓存改进尝试(2) MoSonic:对SubSonic的分布式存储、缓存改进方案尝试(1) Discuz!NT在64位Windows下运行的问题 说说分页 iPhone Web App开发杂感 Katze - 简单的.net "ORM"框架 基于Gettext的asp.net网站多语言解决方案 Django on IronPython and Windows 动态修改.Net StreamReader Encoding编码 恐怖的迅雷 TinyMCE 的音乐插件/mp3 music insert plugin 微软是如何输掉API之战(下)
MoSonic:对SubSonic的分布式存储、缓存改进尝试(4)
问天 · 2011-02-11 · via 博客园 - 问天

之前三篇讲了MoSonic整体设计上的思路参考。这篇讲一下其中的一些细节优化方面遇到的问题。

Cache Money对于查询类型的要求限制的非常死,整个系统变成只有两种查询:

  1. select id from table where simple condition 
  2. select * from table where id = XXX

假设有user表,有password跟is_banned两列。已知user_name,要如何获得is_banned?

Cache Money的限制使得必须得有两个查询:

  1. select id from user where user_name=XXX
  2. select * from user where id=XXX

然后再从第二个查询里面的*去获得is_banned。

有人会认为这很傻,完全可以用一个: select is_banned from user where user_name=XXX的查询来替代,实现减少sql查询次数,以及sql返回的数量两方面的优化。

这是“优化”是一个很有意思的问题。如果我们要认为 select is_banned from user where user_name=XXX 是一个优化;首先必须清楚了解这条sql中数据库究竟做了什么。

首先,要支持where user_name=XXX的查询,user_name这列是必须加索引的。

那么,user_name的索引中包含了什么?这实质上是user_name对user表主键(id)的索引!

数据库要返回is_banned这个数据,实际上它是需要:

  1. 首先查询user_name的索引,获得id的对应的row指针
  2. 根据指针定位至真实的row,并在row找到is_banned的列的数据,才能返回。

上述的数据库内部操作,跟cache money的两个查询实质上是一一对应的。

唯一不同的是,数据库查询是硬盘寻址,而cache money是memcache访问。

memcache与传统硬盘谁快?memcache与SSD硬盘谁快?一个memcache集群与单个SSD物理硬盘谁快?高并发情景下又如何?

我们的初衷是要实现一个分布式的系统以解决性能问题,但为什么突然又要把单个硬盘上的操作视为一个优化?

有人还会认为一开始user_name的索引其实建错了,应该是建user_name + is_banned的联合索引,这样数据库内部在执行select is_banned from user where user_name=XXX 这个查询的时候,就可以直接在索引数据上获得is_banned的值,而无需多一次寻址。

这种又是不是优化?

我们先把user表的分布式放一边,仅考虑单机的情况;我们假设它是优化。

我们原来的设计中,cache money在典型情况下是缓存了100%的查询,对于这种新冒出来的查询,要怎么缓存?

仔细研究的话,这种缓存其实是可以做的;但查询类型增加了,缓存类型增加了,相应的缓存更新策略复杂度也会增加。

这里的实际问题是:在框架中增加这些复杂度/编码量,缓存占用,数据库的索引空间;而换来的查询优化是否值得?

这其实不可一概而论,是要视业务场景而定。

如果,以用户名获得密码的查询在产品业务中的调用异常频繁,甚至就是业务本身100%的调用,那么神马编码复杂度,缓存占用,索引空间都是浮云,这是必须付出的代价。

OK,我们决定做不惜一切代价来实现这个优化;这其实又引入了另一个问题:

MoSonic支持的查询类型是否是优化此业务的唯一选择?

可不可以在不改变MoSonic现有结构的情况下来实现这样的优化?

这个碰巧是有现成的案例,人人网,为了高效的检查一个用户帐号是否有效,专门搞了一整台服务器做中间层缓存所有人人网用户是否被ban的数据,并提供高效的网络接口供系统其他模块调用。

具体可查阅人人网中间层:实践篇

所以,答案是可以。

MoSonic本身是作为一个通用的底层ORM框架,它的分布式支持,缓存支持,都是透明的;但也不强制开发者必须使用;对Cache Money不符合的业务场景,那么是可以把缓存禁用掉;开发者根据自己业务特性去寻求更贴切的缓存方案。

设计一个通用的数据库访问方案,实质上并不应该对特定业务做特定场景下的优化,而应该留出来空间,让开发者在遇到特殊场景时有实现特定优化的可能。

如果说,MoSonic把cache money这层透明缓存做成强制的,开发者连禁用某个表的缓存控制都没有,那才是设计的问题。

上述,实际上仅讨论了一个小细节在单机场景下的情况,同一个问题如果延伸至分布式的场景,也会引发很多很有意思的话题,这篇就先不累述了。