mysql不使用缓存
表对象缓存: 是将某个表对象的字典信息(定义内容)缓存到内存中,用来提高对表的访问效率。某个表被访问过一次后,只要服务器没有关闭且表定义没有被修改的条件下,访问该表,只需要从内存中找到这个已经缓存起来的对象做相应操作即可。
用户访问表时,表对象在缓存时: 通过HASH算法找到TABLE_SHARE,然后每个线程构造各自的实例化TABLE即可。
用户访问表时,当表没有被缓存的情况下: 第一需要打开表,首先需要从系统表中将这个表的所有信息都读入内存中,这些信息包括表名、库名、所有列信息、列的默认值、表的字符集、对应的frm文件路径、所属存储引擎、主键等,将这些信息构造一个TABLE_SHARE结构体,这个结构体是表对象缓存的第一层,所有用户共享访问且为静态不允许修改,它是缓存在table_def_cache(由参数table_definition_cache控制)中的。
而真正与用户打交道的是TABLE_SHARE的衍生品,它对应结构体为TABLE,在被使用前需要将TABLE_SHARE结构体实例化TABLE才能被使用,由每个线程构造各自的实例化TABLE即可。(实例化的TABLE由table_open_cache及table_open_cache_instance控制)
注意1: DDL操作时会将所有instance锁住,而DML操作时instance之间互不干扰。
(DDL statements still require a lock on the entire cache, but such statements are much less frequent than DML statements.)
注意2: 一个线程中如果打开表过多,超过一个instance限制的大小时,是不能跨instance缓存的
(instance大小:table_open_cache / table_open_cache_instances)
表缓存涉及其他参数: 通过下面参数判断table_open_cache参数设置是否合理
table_open_cache_hit:能够从table open cache的free list中找到table则为命中,+1
table_open_cache_misses:与table_open_cache_hit相反,如果找不到则需要重新实例化则+1,通常发生在初始化第一次加载表或超过table_open_cache的设置被淘汰后需要重新实例化。
table_open_cache_overflow:table cache淘汰的数量,每次淘汰+1
opened_tables:已经打开的表数。如果Opened_tables很大,那么table_open_cache的值可能太小了。
open_tables:总的instance (table cache)的总数
2. Mysql中为什么使用InnoDB存储引擎的时候建议关闭回写缓存
MySQL数据库InnoDB存储引擎使用了B策略, InnoDB存储引擎中的恢复机制有几个特点:
A. 在重做Redo Log时,并不关心事务性。 恢复时,没有BEGIN,也没有COMMIT,ROLLBACK的行为。也不关心每个日志是哪个事务的。尽管事务ID等事务相关的内容会记入Redo Log,这些内容只是被当作要操作的数据的一部分。
B. 使用B策略就必须要将Undo Log持久化,而且必须要在写Redo Log之前将对应的Undo Log写入磁盘。Undo和Redo Log的这种关联,使得持久化变得复杂起来。为了降低复杂度,InnoDB将Undo Log看作数据,因此记录Undo Log的操作也会记录到redo log中。这样undo log就可以象数据一样缓存起来,而不用在redo log之前写入磁盘了。
包含Undo Log操作的Redo Log,看起来是这样的:
记录1: <trx1, Undo log insert <undo_insert …>>
记录2: <trx1, insert …>
记录3: <trx2, Undo log insert <undo_update …>>
记录4: <trx2, update …>
记录5: <trx3, Undo log insert <undo_delete …>>
记录6: <trx3, delete …>
C. 到这里,还有一个问题没有弄清楚。既然Redo没有事务性,那岂不是会重新执行被回滚了的事务?确实是这样。同时Innodb也会将事务回滚时的操作也记录到redo log中。回滚操作本质上也是对数据进行修改,因此回滚时对数据的操作也会记录到Redo Log中。
一个回滚了的事务的Redo Log,看起来是这样的:
记录1: <trx1, Undo log insert <undo_insert …>>
记录2: <trx1, insert A…>
记录3: <trx1, Undo log insert <undo_update …>>
记录4: <trx1, update B…>
记录5: <trx1, Undo log insert <undo_delete …>>
记录6: <trx1, delete C…>
记录7: <trx1, insert C>
记录8: <trx1, update B to old value>
记录9: <trx1, delete A>
一个被回滚了的事务在恢复时的操作就是先redo再undo,因此不会破坏数据的一致性.
- InnoDB存储引擎中相关的函数
Redo: recv_recovery_from_checkpoint_start()
Undo: recv_recovery_rollback_active()
Undo Log的Redo Log: trx_undof_page_add_undo_rec_log()
3. MySQL怎么禁止使用缓存以及复杂多表查询的索引优化问题
1、query_cache_size=0 已经禁用了查询缓存,但表数据可能缓存了,flush tables试试,不过操作系统还有一个硬盘缓存,想跟第一次查询之前的状态一致恐怕只能每次重启
2、group by与order by不会用索引的,索引最大的用处就是减小磁盘IO,也就是where时尽量少磁盘IO并读出所有满足条件的记录
4. 怎样清理mysql数据库的缓存
如果数据库是安装在你机器上的 那么你可以暂时把MYSQL关闭 然后进入安装目录 找到data文件夹 这里面就是放置数据库文件的。。你会看到data里面每一个文件夹都对应你一个数据库名称 把他们删除就好了 就彻底没了 不过可别把mysql这个文件夹删了 还有别的文件 比如.err别乱删哦。
如果这个你不会 或者说文件在使用删除不了 那么你就用mysql的可视化工具 比如mysql-front 5.1 进去删除 效果都是一样。
5. 为什么使用mysql主从数据库,而不考虑使用缓存
目的不完全相同
1、数据库信息量大了一般都要使用主从数据库,主写从读。使用主从数据库主要是使数据库能支撑更大的并发,例如:“前台”使用master(主库),“报表”使用slave(从库),那么任何“报表”的sql在slave执行都不会造成“前台”锁表;另外还有方便热备份,支持两个库用不同引擎等好处
2、而程序里使用缓存多是为了减少对数据库访问压力。
6. mysql文件不想用mysql打开
linux系统资源限制
Linux会对用户所占用的系统资源进行限制,MySQL运行在Linux系统下也会受此限制。
查看当前系统的所有限制值
shell> ulimit -a
设置可以同时打开的最大文件数,默认为1024,如不修改打开文件数过多会出现too many open files错误。
shell> ulimit -n
设置最大可用进程数
shell> ulimit -u
一般可通过修改/etc/security/limits.conf文件进行配置。
shell> more /etc/security/limits.conf
* soft nproc 20480
* hard nproc 20480
* soft nofile 65535
* hard nofile 65535
MySQL打开文件限制
mysql> show variables like '%open\_%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| innodb_open_files | 4096 |
| open_files_limit | 65535 |
| table_open_cache | 2048 |
| table_open_cache_instances | 1 |
+----------------------------+-------+
4 rows in set (0.00 sec)
open_files_limit :操作系统允许mysqld打开的文件数量,服务器运行时该变量为系统实际允许打开的值,和启动服务器指定的参数可能不一致。如果该值为0,表示不允许MySQL修改打开的文件数量。
有效的open_files_limit值是基于系统启动指定的open_files_limit,max_connections和table_open_cache计算得到,服务器将会获取三个指标中最大的值,如果三者指标都没有指定,服务器将获得os允许的最大值。
1) 10 + max_connections + (table_open_cache * 2)
2) max_connections * 5
3) 启动时设定的open_files_limit,如果没有指定默认为5000
innodb_open_files:指定MySQL可同时打开.ibd文件的最大个数,最小为10,默认300。此选项只针对InnoDB表打开的.ibd文件描述符,独立于open_files_limit。
table_open_cache:所有线程打开表的数目。它的作用就是缓存表文件描述符,降低打开关闭表的频率, 如果这个参数设置得过小,就不得不关闭一些已打开的表以便为缓存新表,从而出现频繁的打开关闭MyISAM表文件的情况,而INNODB表的打开不受这个参数控制,而是放到其数据字典当中,即在ibd文件中。当Opened_tables状态值较大,且不经常使用FLUSH TABLES 关闭并重新打开表,就需要增加该值。
table_open_cache_instances:表缓存实例数,为通过减小会话间争用提高扩展性,表缓存会分区为table_open_cache/table_open_cache_instances大小的较小的缓存实例。DML语句会话只需要锁定所在缓存实例,这样多个会话访问表缓存时就可提升性能(DDL语句仍会锁定整个缓存)。默认该值为1,当16核以上可设置为8或16。
table_definition_cache:缓存表定义(.frm)文件的数量。如果表较多,可以增大该值加快打开表。与一般表缓存不同,表定义缓存不占用文件描述符,占用空间也小。最小为400,上线为2000,默认为:
400 + (table_open_cache / 2)。如果打开表数量高于table_definition_cache,则会通过LRU机制搜索表空间LRU文件列表并刷新列表。对于InnoDB,打开文件的限制为max(table_definition_cache, innodb_open_files)。
MySQL文件打开状态
mysql> show global status like '%open%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Com_ha_open | 0 |
| Com_show_open_tables | 1 |
| Innodb_num_open_files | 19 |
| Open_files | 3 |
| Open_streams | 0 |
| Open_table_definitions | 8 |
| Open_tables | 8 |
| Opened_files | 509 |
| Opened_table_definitions | 116 |
| Opened_tables | 90 |
| Slave_open_temp_tables | 0 |
| Table_open_cache_hits | 3254 |
| Table_open_cache_misses | 90 |
| Table_open_cache_overflows | 0 |
+----------------------------+-------+
14 rows in set (0.00 sec)
Open_table_definitions:代表当前缓存了多少.frm文件。
Opened_table_definitions:代表自MySQL启动后,缓存了.frm文件的数量。 需要注意的是.frm文件是MySQL用于存放表结构的文件,
对应myisam和innodb存储引擎都必须有的,可以通过show open tables 查看 这2个变量的值。
Open_tables:代表当前打开的表个数
Opened_tables:代表自MySQL启动后,打开过的表个数,如该值过大,可能是table_open_cache设置太小。
Open_files:打开文件的个数。服务器层打开的一般文件,不包含sockets 或 pipes类型文件,也不包含内部函数打开的文件。
Opened_files:通过使用my_open()系统函数打开的文件数。
Table_open_cache_hits:打开表缓存查找的命中数。
Table_open_cache_misses:打开表缓存查找的未命中数。
Table_open_cache_overflows:打开表缓存溢出数。
MySQL如何打开关闭表
由于MySQL是多线程的,因此可能存在多个会话同时根据指定表进行查询。为解决同一个表在不同会话状态不一致,该表会由每个会话独立的打开,这样MySQL会消耗内存但会提高性能。
table_open_cache同时会跟max_connections相关。如200个并发连接线程,指定的表缓存至少为200*N,N为每个连接关联的最大表数量。
以下几种情况MySQL会关闭未使用的表并将其从表缓存中删除:
表缓存已满,线程将要打开不在缓存中的表。
缓存中的表多于table_open_cache且缓存中的表不被任何线程使用。
当发生表刷新操作(flush tables)
当表缓存满后,服务器将执行以下操作:
当前不使用的表将被释放,先释放最近最少使用的表
当新表需要被打开,但是缓存已满且无表可以被释放,服务器将会根据需要临时扩展缓存,当临时扩展缓存中的表从使用变为未使用状态,表将被关闭,扩充的临时缓存将被释放。
文件打开常见问题
数据库报错:
[ERROR] /opt/mysql/bin/mysqld: Can't open file: './tpcc/sbtest98.frm' (errno: 24 - Too many open files)
查看os最大允许打开数
shell> ulimit -n
65535
查看数据库打开设定最大打开文件数
mysql> show global variables like 'open_files_limit';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| open_files_limit | 500 |
+------------------+-------+
1 row in set (0.00 sec)
查看当前数据库已经打开的文件描述符
shell>ll /proc/24012/fd | wc
501 5507 41673
调整open_files_limit设定并重启生效。
7. MySQL缓存
mysql 开启查询缓存可以有两种方法来开启一种是使用set命令来进行开启,另一种是直接修改my.ini文件来直接设置都是非常的简单的哦。
开启缓存,设置缓存大小,具体实施如下:
windows下是my.ini,linux下是my.cnf;
在配置文件的最后追加上:
需要重启mysql生效;
b) 开启缓存,两种方式:
a)使用mysql命令:
如果报错:
Query cache is disabled; restart the server with query_cache_type=1 to enable it,还是老老实实的该配置文件,然后重启吧,原因如下:
查看是否设置成功
show variables like "%query_cache%" 查看是否设置成功:
当然如果你的数据表有更新怎么办,没关系mysql默认会和这个表有关系的缓存删掉,下次查询的时候会直接读表然后再缓存
下面是一个简单的例子:
以上的相关内容就是对mysql缓存查询和设置的介绍,望你能有所收获。
一般,我们会把 query_cache_type 设置为 ON,默认情况下应该是ON
query_cache_type有3个值 0代表关闭查询缓存OFF,1代表开启ON,2(DEMAND)代表当sql语句中有SQL_CACHE关键词时才缓存,如:
这样 当我们执行 select id,name from tableName; 这样就会用到查询缓存。
①在 query_cache_type 打开的情况下,如果你不想使用缓存,需要指明
select sql_no_cache id,name from tableName;
②当sql中用到mysql函数,也不会缓存
当然也可以禁用查询缓存: mysql> set session query_cache_type=off;
上面的显示,表示设置查询缓存是可用的。
表示查询缓存大小,也就是分配内存大小给查询缓存,如果你分配大小为0,
那么 第一步 和 第二步 起不到作用,还是没有任何效果。
上面是 mysql6.0设置默认的,之前的版本好像默认是0的,那么就要自己设置下。
设置
这里是设置1M左右,900多K。
再次查看下:
显示我们设置新的大小,表示设置成功。
例如: 如果查询结果很大, 也缓存????这个明显是不可能的。
MySql 可以设置一个最大的缓存值,当你查询缓存数结果数据超过这个值就不会
进行缓存。缺省为1M,也就是超过了1M查询结果就不会缓存。
这个是默认的数值,如果需要修改,就像设置缓存大小一样设置,使用set
重新指定大小。
好了,通过4个步骤就可以 打开了查询缓存,具体值的大小和查询的方式 这个因不同
的情况来指定了。
mysql查询缓存相关变量
MySQL 提供了一系列的 Global Status 来记录 Query Cache 的当前状态,具体如下:
Qcache_free_blocks:目前还处于空闲状态的 Query Cache 中内存 Block 数目
Qcache_free_memory:目前还处于空闲状态的 Query Cache 内存总量
Qcache_hits:Query Cache 命中次数
Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次数,也就是没有命中的次数
Qcache_lowmem_prunes:当 Query Cache 内存容量不够,需要从中删除老的 Query Cache 以给新的 Cache 对象使用的次数
Qcache_not_cached:没有被 Cache 的 SQL 数,包括无法被 Cache 的 SQL 以及由于 query_cache_type 设置的不会被 Cache 的 SQL
Qcache_queries_in_cache:目前在 Query Cache 中的 SQL 数量
Qcache_total_blocks:Query Cache 中总的 Block 数量
检查是否从查询缓存中受益的最简单的办法就是检查缓存命中率
当服务器收到SELECT 语句的时候,Qcache_hits 和Com_select 这两个变量会根据查询缓存
的情况进行递增
查询缓存命中率的计算公式是:Qcache_hits/(Qcache_hits + Com_select)。
query_cache_min_res_unit的配置是一柄”双刃剑”,默认是4KB,设置值大对大数据查询有好处,但如果你的查询都是小数据 查询,就容易造成内存碎片和浪费。
查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
如果查询缓存碎片率超过20%,可以用FLUSH QUERY CACHE整理缓存碎片,或者试试减小query_cache_min_res_unit,如果你的查询都是小数据量的话。
查询缓存利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%
查询缓存利用率在25%以下的话说明query_cache_size设置的过大,可适当减小;查询缓存利用率在80%以上而且 Qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小,要不就是碎片太多。
查询缓存命中率 = (Qcache_hits - Qcache_inserts) / Qcache_hits * 100%
示例服务器 查询缓存碎片率 = 20.46%,查询缓存利用率 = 62.26%,查询缓存命中率 = 1.94%,命中率很差,可能写操作比较频繁吧,而且可能有些碎片。
查询缓存可以看做是SQL文本和查询结果的映射。如果第二次查询的SQL和第一次查询的SQL完全相同(注意必须是完全相同,即使多一个空格或者大小写不同都认为不同)且开启了查询缓存,那么第二次查询就直接从查询缓存中取结果,可以通过下面的SQL来查看缓存命中次数(是个累加值):
另外即使完全相同的SQL,如果使用不同的字符集、不同的协议等也会被认为是不同的查询而分别进行缓存。
在表的结构或数据发生改变时,查询缓存中的数据不再有效。有这些INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE会导致缓存数据失效。所以查询缓存适合有大量相同查询的应用,不适合有大量数据更新的应用。
可以使用下面三个SQL来清理查询缓存:
1、FLUSH QUERY CACHE; // 清理查询缓存内存碎片。
2、RESET QUERY CACHE; // 从查询缓存中移出所有查询。
3、FLUSH TABLES; //关闭所有打开的表,同时该操作将会清空查询缓存中的内容。
Query Cache是MySQL Server层的一个非常好的特性,对于小数据集或访问量非常集中的应用场景,有非常好的性能提升,但是Query Cache引入了一些新的问题,而且大部分场景下比较鸡肋,官方打算弃用了
参考:
https://www.cnblogs.com/wangzhuxing/p/5223881.html
https://www.cnblogs.com/lixiuran/archive/2014/03/08/3588654.html
8. 如何清理mysql数据库缓存数据
1、打开mysql的客户端 这里使用navicat,连接数据库,等到navicat主页面,双击需要操作的数据库连接。
9. 数据多的时候为什么要使用redis而不用mysql
通常来说,当数据多、并发量大的时候,架构中可以引入Redis,帮助提升架构的整体性能,减少Mysql(或其他数据库)的压力,但不是使用Redis,就不用MySQL。
因为Redis的性能十分优越,可以支持每秒十几万此的读/写操作,并且它还支持持久化、集群部署、分布式、主从同步等,Redis在高并发的场景下数据的安全和一致性,所以它经常用于两个场景:
缓存
判断数据是否适合缓存到Redis中,可以从几个方面考虑: 会经常查询么?命中率如何?写操作多么?数据大小?
我们经常采用这样的方式将数据刷到Redis中:查询的请求过来,现在Redis中查询,如果查询不到,就查询数据库拿到数据,再放到缓存中,这样第二次相同的查询请求过来,就可以直接在Redis中拿到数据;不过要注意【缓存穿透】的问题。
缓存的刷新会比较复杂,通常是修改完数据库之后,还需要对Redis中的数据进行操作;代码很简单,但是需要保证这两步为同一事务,或最终的事务一致性。
高速读写
常见的就是计数器,比如一篇文章的阅读量,不可能每一次阅读就在数据库里面update一次。
高并发的场景很适合使用Redis,比如双11秒杀,库存一共就一千件,到了秒杀的时间,通常会在极为短暂的时间内,有数万级的请求达到服务器,如果使用数据库的话,很可能在这一瞬间造成数据库的崩溃,所以通常会使用Redis(秒杀的场景会比较复杂,Redis只是其中之一,例如如果请求超过某个数量的时候,多余的请求就会被限流)。
这种高并发的场景,是当请求达到服务器的时候,直接在Redis上读写,请求不会访问到数据库;程序会在合适的时间,比如一千件库存都被秒杀,再将数据批量写到数据库中。
所以通常来说,在必要的时候引入Redis,可以减少MySQL(或其他)数据库的压力,两者不是替代的关系 。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。
Redis和MySQL的应用场景是不同的。
通常来说,没有说用Redis就不用MySQL的这种情况。
因为Redis是一种非关系型数据库(NoSQL),而MySQL是一种关系型数据库。
和Redis同类的数据库还有MongoDB和Memchache(其实并没有持久化数据)
那关系型数据库现在常用的一般有MySQL,SQL Server,Oracle。
我们先来了解一下关系型数据库和非关系型数据库的区别吧。
1.存储方式关系型数据库是表格式的,因此存储在表的行和列中。他们之间很容易关联协作存储,提取数据很方便。而Nosql数据库则与其相反,他是大块的组合在一起。通常存储在数据集中,就像文档、键值对或者图结构。
2.存储结构关系型数据库对应的是结构化数据,数据表都预先定义了结构(列的定义),结构描述了数据的形式和内容。这一点对数据建模至关重要,虽然预定义结构带来了可靠性和稳定性,但是修改这些数据比较困难。而Nosql数据库基于动态结构,使用与非结构化数据。因为Nosql数据库是动态结构,可以很容易适应数据类型和结构的变化。
3.存储规范关系型数据库的数据存储为了更高的规范性,把数据分割为最小的关系表以避免重复,获得精简的空间利用。虽然管理起来很清晰,但是单个操作设计到多张表的时候,数据管理就显得有点麻烦。而Nosql数据存储在平面数据集中,数据经常可能会重复。单个数据库很少被分隔开,而是存储成了一个整体,这样整块数据更加便于读写
4.存储扩展这可能是两者之间最大的区别,关系型数据库是纵向扩展,也就是说想要提高处理能力,要使用速度更快的计算机。因为数据存储在关系表中,操作的性能瓶颈可能涉及到多个表,需要通过提升计算机性能来克服。虽然有很大的扩展空间,但是最终会达到纵向扩展的上限。而Nosql数据库是横向扩展的,它的存储天然就是分布式的,可以通过给资源池添加更多的普通数据库服务器来分担负载。
5.查询方式关系型数据库通过结构化查询语言来操作数据库(就是我们通常说的SQL)。SQL支持数据库CURD操作的功能非常强大,是业界的标准用法。而Nosql查询以块为单元操作数据,使用的是非结构化查询语言(UnQl),它是没有标准的。关系型数据库表中主键的概念对应Nosql中存储文档的ID。关系型数据库使用预定义优化方式(比如索引)来加快查询操作,而Nosql更简单更精确的数据访问模式。
6.事务关系型数据库遵循ACID规则(原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)),而Nosql数据库遵循BASE原则(基本可用(Basically Availble)、软/柔性事务(Soft-state )、最终一致性(Eventual Consistency))。由于关系型数据库的数据强一致性,所以对事务的支持很好。关系型数据库支持对事务原子性细粒度控制,并且易于回滚事务。而Nosql数据库是在CAP(一致性、可用性、分区容忍度)中任选两项,因为基于节点的分布式系统中,很难全部满足,所以对事务的支持不是很好,虽然也可以使用事务,但是并不是Nosql的闪光点。
7.性能关系型数据库为了维护数据的一致性付出了巨大的代价,读写性能比较差。在面对高并发读写性能非常差,面对海量数据的时候效率非常低。而Nosql存储的格式都是key-value类型的,并且存储在内存中,非常容易存储,而且对于数据的 一致性是 弱要求。Nosql无需sql的解析,提高了读写性能。
8.授权方式大多数的关系型数据库都是付费的并且价格昂贵,成本较大(MySQL是开源的,所以应用的场景最多),而Nosql数据库通常都是开源的。
所以,在实际的应用环境中,我们一般会使用MySQL存储我们的业务过程中的数据,因为这些数据之间的关系比较复杂,我们常常会需要在查询一个表的数据时候,将其他关系表的数据查询出来,例如,查询某个用户的订单,那至少是需要用户表和订单表的数据。
查询某个商品的销售数据,那可能就会需要用户表,订单表,订单明细表,商品表等等。
而在这样的使用场景中,我们使用Redis来存储的话,也就是KeyValue形式存储的话,其实并不能满足我们的需要。
即使Redis的读取效率再高,我们也没法用。
但,对于某些没有关联少,且需要高频率读写,我们使用Redis就能够很好的提高整个体统的并发能力。
例如商品的库存信息,我们虽然在MySQL中会有这样的字段,但是我们并不想MySQL的数据库被高频的读写,因为使用这样会导致我的商品表或者库存表IO非常高,从而影响整个体统的效率。
所以,对于这样的数据,且有没有什么复杂逻辑关系(就只是隶属于SKU)的数据,我们就可以放在Redis里面,下单直接在Redis中减掉库存,这样,我们的订单的并发能力就能够提高了。
个人觉得应该站出来更正一下,相反的数据量大,更不应该用redis。
因为redis是内存型数据库啊,是放在内存里的。
设想一下,假如你的电脑100G的资料,都用redis来存储,那么你需要100G以上的内存!
使用场景Redis最明显的用例之一是将其用作缓存。只是保存热数据,或者具有过期的cache。
例如facebook,使用Memcached来作为其会话缓存。
总之,没有见过哪个大公司数据量大了,换掉mysql用redis的。
题主你错了,不是用redis代替MySQL,而是引入redis来优化。
BAT里越来越多的项目组已经采用了redis+MySQL的架构来开发平台工具。
如题主所说,当数据多的时候,MySQL的查询效率会大打折扣。我们通常默认如果查询的字段包含索引的话,返回是毫秒级别的。但是在实际工作中,我曾经遇到过一张包含10个字段的表,1800万+条数据,当某种场景下,我们不得不根据一个未加索引的字段进行精确查询的时候,单条sql语句的执行时长有时能够达到2min以上,就更别提如果用like这种模糊查询的话,其效率将会多么低下。
我们最开始是希望能够通过增加索引的方式解决,但是面对千万级别的数据量,我们也不敢贸然加索引,因为一旦数据库hang住,期间的所有数据库写入请求都会被放到等待队列中,如果请求是通过http请求发过来的,很有可能导致服务发生分钟级别的超时不响应。
经过一番调研,最终敲定的解决方案是引入redis作为缓存。redis具有运行效率高,数据查询速度快,支持多种存储类型以及事务等优势,我们把经常读取,而不经常改动的数据放入redis中,服务器读取这类数据的时候时候,直接与redis通信,极大的缓解了MySQL的压力。
然而,我在上面也说了,是redis+MySQL结合的方式,而不是替代。原因就是redis虽然读写很快,但是不适合做数据持久层,主要原因是使用redis做数据落盘是要以效率作为代价的,即每隔制定的时间,redis就要去进行数据备份/落盘,这对于单线程的它来说,势必会因“分心”而影响效率,结果得不偿失。
楼主你好,首先纠正下,数据多并不是一定就用Redis,Redis归属于NoSQL数据库中,其特点拥有高性能读写数据速度,主要解决业务效率瓶颈。下面就详细说下Redis的相比MySQL优点。( 关于Redis详细了解参见我近期文章:https://www.toutiao.com/i6543810796214813187/ )
读写异常快
Redis非常快,每秒可执行大约10万次的读写速度。
Redis支持丰富的数据类型,有二进制字符串、列表、集合、排序集和散列等等。这使得Redis很容易被用来解决各种问题,因为我们知道哪些问题可以更好使用地哪些数据类型来处理解决。
原子性Redis的所有操作都是原子操作,这确保如果两个客户端并发访问,Redis服务器能接收更新的值。
丰富实用工具 支持异机主从复制Redis支持主从复制的配置,它可以实现主服务器的完全拷贝。
以上为开发者青睐Redis的主要几个可取之处。但是,请注意实际生产环境中企业都是结合Redis和MySQL的特定进行不同应用场景的取舍。 如缓存——热数据、计数器、消息队列(与ActiveMQ,RocketMQ等工具类似)、位操作(大数据处理)、分布式锁与单线程机制、最新列表(如新闻列表页面最新的新闻列表)以及排行榜等等 可以看见Redis大显身手的场景。可是对于严谨的数据准确度和复杂的关系型应用MySQL等关系型数据库依然不可替。
web应用中一般采用MySQL+Redis的方式,web应用每次先访问Redis,如果没有找到数据,才去访问MySQL。
本质区别1、mysql:数据放在磁盘 redis:数据放在内存。
首先要知道mysql存储在磁盘里,redis存储在内存里,redis既可以用来做持久存储,也可以做缓存,而目前大多数公司的存储都是mysql + redis,mysql作为主存储,redis作为辅助存储被用作缓存,加快访问读取的速度,提高性能。
使用场景区别1、mysql支持sql查询,可以实现一些关联的查询以及统计;
2、redis对内存要求比较高,在有限的条件下不能把所有数据都放在redis;
3、mysql偏向于存数据,redis偏向于快速取数据,但redis查询复杂的表关系时不如mysql,所以可以把热门的数据放redis,mysql存基本数据。
mysql的运行机制mysql作为持久化存储的关系型数据库,相对薄弱的地方在于每次请求访问数据库时,都存在着I/O操作,如果反复频繁的访问数据库。第一:会在反复链接数据库上花费大量时间,从而导致运行效率过慢;第二:反复地访问数据库也会导致数据库的负载过高,那么此时缓存的概念就衍生了出来。
Redis持久化由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时mp到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。
redis是放在内存的~!
数据量多少绝对不是选择redis和mysql的准则,因为无论是mysql和redis都可以集群扩展,约束它们的只是硬件(即你有没有那么多钱搭建上千个组成的集群),我个人觉得数据读取的快慢可能是选择的标准之一,另外工作中往往是两者同是使用,因为mysql存储在硬盘,做持久化存储,而redis存储在内存中做缓存提升效率。
关系型数据库是必不可少的,因为只有关系型数据库才能提供给你各种各样的查询方式。如果有一系列的数据会频繁的查询,那么就用redis进行非持久化的存储,以供查询使用,是解决并发性能问题的其中一个手段
10. mysql查询时怎么不用缓存
设置好查询缓存的大小就行了。比如设置个20MB.
SET GLOBAL QUERY_CACHE_SIZE=20000000;
mysql会将查询SQL和结果集存到缓存中,等下次遇到相同的SQL语句时,结果集从缓存中读取。
不设置就不用缓存了