memcached缓存mysql
Ⅰ mysql有基于LRU缓冲池,其它辅助缓存如memcached和redis的意义应该就不需要了,还是有其它需要的理由
1、首先明确是不是一定要上缓存,当前架构的瓶颈在哪里,若瓶颈真是数据库操作上,再继续往下看。
2、明确memcached和redis的区别,到底要使用哪个。前者终究是个缓存,不可能永久保存数据(LRU机制),支持分布式,后者除了缓存的同时也支持把数据持久化到磁盘等,redis要自己去实现分布式缓存(貌似最新版本的已集成),自己去实现一致性hash。因为不知道应用场景,不好说一定要用memcache还是redis,说不定用mongodb会更好,比如在存储日志方面。
3、缓存量大但又不常变化的数据,比如评论。
4、思路是对的,清晰明了,读DB前,先读缓存,如果有直接返回,如果没有再读DB,然后写入缓存层并返回。
5、考虑是否需要主从,读写分离,考虑是否分布式部署,考虑是否后续水平伸缩。
6、想要一劳永逸,后续维护和扩展方便,那就将现有的代码架构优化,按你说的替换数据库组件需要改动大量代码,说明当前架构存在问题。可以利用现有的一些框架,比如SpringMVC,将应用层和业务层和数据库层解耦。再上缓存之前把这些做好。
7、把读取缓存等操作做成服务组件,对业务层提供服务,业务层对应用层提供服务。
8、保留原始数据库组件,优化成服务组件,方便后续业务层灵活调用缓存或者是数据库。
9、不建议一次性全量上缓存,最开始不动核心业务,可以将边缘业务先换成缓存组件,一步步换至核心业务。
10、刷新内存,以memcached为例,新增,修改和删除操作,一般采用lazy load的策略,即新增时只写入数据库,并不会马上更新Memcached,而是等到再次读取时才会加载到Memcached中,修改和删除操作也是更新 数据库,然后将Memcached中的数据标记为失效,等待下次读取时再加载。
大方向两种方案:
1、脚本同步:自己写脚本将数据库数据写入到redis/memcached。这就涉及到实时数据变更的问题(mysql row binlog的实时分析),binlog增量订阅Alibaba 的canal ,以及缓存层数据 丢失/失效 后的数据同步恢复问题。
2、业务层实现:先读取nosql缓存层,没有数据再读取mysql层,并写入数据到nosql。nosql层做好多节点分布式(一致性hash),以及节点失效后替代方案(多层hash寻找相邻替代节点),和数据震荡恢复了。
Ⅱ 解决MYSQL查询瓶颈问题提升读取效率无锁查询技巧mysql不加锁查询
在大规模数据存储和处理中,MYSQL数据库是一个非常常用和有力的工具。但是,在查询数据的过程中,可能会出现瓶颈和效率低下的问题,特别是在高并发读取的场景中。针对这种问题,我们可以采用无锁查询技巧,从而大幅提升读取效率。
一、什么是无锁查询
传统数据库在并发读取数据时,会发生锁定的情况。例如,在一条记录被第一个请求查询时,此时其他请求将无法读取该记录,只能等待。这种方式本身是合理的,可以避免数据冲突和不一致性,但是在高并发场景下,会导致性能瓶颈和资源占用。
而无锁查询,则是一种基于CAS(Compare and Swap)操作的原子性操作,它使得多个线程可以同时读取同一条记录,而不会造成数据不一致。
二、如何实现无锁查询技巧
1.使用load data local infile代替insert into
在MYSQL中,我们可以使用load data local infile语句将数据一次性导入到数据库中,从而避免了大量的写入操作。这个操作方式不仅可以提高写入效率,还避免了数据冲突。
2.使用memcached或redis缓存查询结果
在高并发读取时,我们可以将查询的结果缓存到memcached或redis中,从而避免多次查询同一记录的问题。这种方式可以大幅提高查询效率,减少数据库的压力。
3.使用第三方插件进行无锁操作
一些第三方插件,例如MyISAM存储引擎以及Apache Cassandra等,都提供了一些无锁查询操作。我们可以根据具体的需求选择一个最适合的插件,来提高查询效率和性能。
三、案例分析:使用无锁查询技巧提升MYSQL读取效率
下面给出一个实际的案例,演示如何通过无锁查询技巧来提高MYSQL的读取效率。
假设我们有一个用户表user,其中包含以下字段:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(11) NOT NULL,
`gender` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
我们希望查询所有年龄大于20岁的男性用户,并将结果缓存到memcached中。
使用普通查询方式的代码如下:
$mysqli = new mysqli(“localhost”, “username”, “password”, “test”);
if ($mysqli->connect_errno) {
die(“Fled to connect to MySQL: (” . $mysqli->connect_errno . “) ” . $mysqli->connect_error);
}
$query=”SELECT * FROM user WHERE age>20 AND gender=’male'”;
$result=mysqli_query($mysqli,$query);
while($row=mysqli_fetch_assoc($result)){
//do something with the result
}
mysqli_close($mysqli);
使用无锁查询技巧的代码如下:
$mysqli = new mysqli(“localhost”, “username”, “password”, “test”);
if ($mysqli->connect_errno) {
die(“Fled to connect to MySQL: (” . $mysqli->connect_errno . “) ” . $mysqli->connect_error);
}
$memcache = new Memcache;
$memcache->connect(‘localhost’, 11211) or die (“Could not connect”);
$query=”SELECT * FROM user WHERE age>20 AND gender=’male'”;
$cache_key=md5($query);
if($cache_result=$memcache->get($cache_key)){
while($row=mysqli_fetch_assoc($cache_result)){
//do something with the result
}
}else{
$result=mysqli_query($mysqli,$query);
while($row=mysqli_fetch_assoc($result)){
$cache_result[]=$row;
//do something with the result
}
$memcache->set($cache_key,$cache_result,0,1200);
}
mysqli_close($mysqli);
如上代码可以看出,我们先使用memcached进行查询结果的缓存,然后再从缓存中读取数据。这样就避免了多次查询同一记录的问题,大幅提高了读取效率和性能。
四、总结
无锁查询技巧是一种提高MYSQL读取效率和性能的有效方法,在高并发读取场景下尤其适用。我们可以通过几种方法来实现无锁查询,例如使用load data local infile代替insert into、使用memcached或redis缓存查询结果、使用第三方插件进行无锁操作等。在实际应用中,我们应该根据具体的需求来选择合适的方法,以达到最佳的效果。