扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
redis缓存其实就是把经常访问的数据放到redis里面,用户查询的时候先去redis查询,没有查到就执行sql语句查询,同时把数据同步到redis里面。redis只做读操作,在内存中查询速度快。
在和田等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站制作、网站建设、外贸网站建设 网站设计制作按需设计网站,公司网站建设,企业网站建设,成都品牌网站建设,成都全网营销,成都外贸网站建设,和田网站建设费用合理。
使用redis做缓存必须解决两个问题,首先就是确定用何种数据结构存储来自mysql的数据;确定数据结构之后就是需要确定用什么标识来作为数据的key。
mysql是按照表存储数据的,这些表是由若干行组成。每一次执行select查询,mysql都会返回一个结果集,这个结果是由若干行组成的。redis有五种数据结构:列表list,哈希hash,字符串string,集合set,sorted set(有序集合),对比几种数据结构,string和hash是比较适合存储行的数据结构,可以把数据转成json字符串存入redis。
全量遍历键: keys pattern keys *
有人说 KEYS 相当于关系性数据的库的 select * ,在生产环境几乎是要禁用的
不管上面说的对不对, keys 肯定是有风险的。那我们就换一种方案,在存数据的时候。把数据的键存一下,也存到redis里面选hash类型,那么取的时候就可以直接通过这个hash获取所有的值,自我感觉非常好用!
可以通过如下命令查看现在缓存的情况
[java] view plain copy
mysql show status like 'qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 10475424 |
| Qcache_hits | 1 |
| Qcache_inserts | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+----------+
8 rows in set (0.00 sec)
其中各个参数的意义如下:
Qcache_free_blocks:缓存中相邻内存块的个数。数目大说明可能有碎片。FLUSH QUERY CACHE会对缓存中的碎片进行整理,从而得到一个空闲块。
Qcache_free_memory:缓存中的空闲内存。
Qcache_hits:每次查询在缓存中命中时就增大
Qcache_inserts:每次插入一个查询时就增大。命中次数除以插入次数就是不中比率。
Qcache_lowmem_prunes:缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看;如果这个 数字在不断增长,就表示可能碎片非常严重,或者内存很少。(上面的 free_blocks和free_memory可以告诉您属于哪种情况)
Qcache_not_cached:不适合进行缓存的查询的数量,通常是由于这些查询不是 SELECT 语句或者用了now()之类的函数。
Qcache_queries_in_cache:当前缓存的查询(和响应)的数量。
Qcache_total_blocks:缓存中块的数量。
当在使用中,查询缓存会存储一个 SELECT 查询的文本与被传送到客户端的相应结果。如果之后接收到一个同样的查询,服务器将从查询缓存中检索结果,而不是再次分析和执行这个同样的查询。
注意:查询缓存绝不返回过期数据。当数据被修改后,在查询缓存中的任何相关词条均被转储清除。
在某些表并不经常更改,而你又对它执行大量的相同查询时,查询缓存将是非常有用的。对于许多 WEB 服务器使用大量的动态信息,这是一个很典型的情况。
下面是查询缓存的一个性能数据。(这些结果的产生,是通过在一个 a Linux Alpha 2 x 500 MHz、2GB RAM 和 64MB 查询缓存上执行 MySQL 基准套件和到的):
如果你执行的所有查询均是简单的(比如从表中一行一行的选取);但是仍然是不同的,所以该查询不能被缓冲,查询缓存处于活动时,开销为 13%。这可以被看作是最差的情况。然而,在实际情况下,查询是比我们的简单示例要复杂得多的,所以开销通常显着得低。
在只有一行记录表中搜索一行后,搜索将快 238% 。这可以被认为是接近于对一个被缓冲的查询所期望的最小的加速。
如果你希望禁用查询缓存,设置 query_cache_size=0。禁用了查询缓存,将没有明显的开销。(在配置选项 --without-query-cache 的帮助下,查询缓存可以被排除在外码之外)
查询在分析之前先被比较,因而
SELECT * FROM tbl_name和Select * from tbl_name
对于查询缓存被当作是不同的查询,因而查询需要严格的一致(字节对字节的),才会被认为是同样的。 另外,如果一个客户端使用一个新的连接协议格式或不同于其它客户端的另一个字符集,一个查询将被视为不同的。
使用不同数据库的,使用不同协议版本的,或使用不同的缺省字符串的查询将被认为是不同的查询,并将分别的缓冲。
高速缓冲不对 SELECT CALC_ROWS … 和 SELECT FOUND_ROWS() … 类型的查询起作用,因为找到的行的数目也是被存储在缓冲里的。
如果查询结果被从查询缓存中返回,那么状态变量 Com_select 将不会被增加,但是 Qcache_hits 却会增加。
查看章节 6.9.4 查询缓存的状态和维护。
如果一个表发生的改变 (INSERT, UPDATE, DELETE, TRUNCATE, ALTER 或 DROP TABLE|DATABASE),那么所有这张表使用的缓冲的查询(可能通过一个 MRG_MyISAM 表!)将被得失效,并从缓冲中移除。
InnoDB 表的事务所做的更改将在一个 COMMIT 被完成时,使数据失效。
如果一个查询包括下面的函数,它将不能被缓冲:
函数 函数 函数
User-Defined Functions CONNECTION_ID FOUND_ROWS
GET_LOCK RELEASE_LOCK LOAD_FILE
MASTER_POS_WAIT NOW SYSDATE
CURRENT_TIMESTAMP CURDATE CURRENT_DATE
CURTIME CURRENT_TIME DATABASE
ENCRYPT (只有一个参数调用) LAST_INSERT_ID RAND
UNIX_TIMESTAMP (无参数调用) USER BENCHMARK
如果一个查询包含用户变量,引用 MySQL 系统数据库,或下列之一的格式,SELECT … IN SHARE MODE, SELECT … INTO OUTFILE …, SELECT … INTO DUMPFILE … 或 SELECT * FROM AUTOINCREMENT_FIELD IS NULL (检索最后一个插入 ID - ODBC 语句),该查询亦不可以被缓存。
然而,FOUND ROWS() 将返回正确的值,即使先前的查询是从缓存中读取的。
万一一个查询不使用任何表,或使用临时表,或用户对任何相关表有一个列权限,那么查询将不会被缓存。
在一个查询从查询缓存中读取前,MySQL 将检查用户对所有相关的数据库和表有 SELECT 权限。
MySQL缓存机制简单的说就是缓存sql文本及查询结果,如果运行相同的sql,服务器直接从缓存中取到结果,而不需要再去解析和执行sql。如果表更改 了,那么使用这个表的所有缓冲查询将不再有效,查询缓存值的相关条目被清空。更改指的是表中任何数据或是结构的改变,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改变了的表的使用MERGE表的查询。显然,这对于频繁更新的表,查询缓存是不适合的,而对于一些不常改变数据且有 大量相同sql查询的表,查询缓存会节约很大的性能。命中条件
缓存存在一个hash表中,通过查询SQL,查询数据库,客户端协议等作为key.在判断是否命中前,MySQL不会解析SQL,而是直接使用SQL去查询缓存,SQL任何字符上的不同,如空格,注释,都会导致缓存不命中.
如果查询中有不确定数据,例如CURRENT_DATE()和NOW()函数,那么查询完毕后则不会被缓存.所以,包含不确定数据的查询是肯定不会找到可用缓存的
; 从 MySQL 开始 MySQL server 有一个重要的特征 Query Cache 当在使用中 查询缓存会存储一个 SELECT 查询的文本与被传送到客户端的相应结果 如果之后接收到一个同样的查询 服务器将从查询缓存中检索结果 而不是再次分析和执行这个同样的查询 注意 查询缓存绝不返回过期数据 当数据被修改后 在查询缓存中的任何相关词条均被转储清除 在某些表并不经常更改 而你又对它执行大量的相同查询时 查询缓存将是非常有用的 对于许多 WEB 服务器使用大量的动态信息 这是一个很典型的情况 下面是查询缓存的一个性能数据 (这些结果的产生 是通过在一个 a Linux Alpha x MHz GB RAM 和 MB 查询缓存上执行 MySQL 基准套件和到的) 如果你执行的所有查询均是简单的(比如从表中一行一行的选取) 但是仍然是不同的 所以该查询不能被缓冲 查询缓存处于活动时 开销为 % 这可以被看作是最差的情况 然而 在实际情况下 查询是比我们的简单示例要复杂得多的 所以开销通常显著得低 在只有一行记录表中搜索一行后 搜索将快 % 这可以被认为是接近于对一个被缓冲的查询所期望的最小的加速 如果你希望禁用查询缓存 设置 query_cache_size= 禁用了查询缓存 将没有明显的开销 (在配置选项 without query cache 的帮助下 查询缓存可以被排除在外码之外) 查询缓存如何运作 查询在分析之前先被比较 因而 SELECT * FROM tbl_name 和 Select * from tbl_name 对于查询缓存被当作是不同的查询 因而查询需要严格的一致(字节对字节的) 才会被认为是同样的 另外 如果一个客户端使用一个新的连接协议格式或不同于其它客户端的另一个字符集 一个查询将被视为不同的 使用不同数据库的 使用不同协议版本的 或使用不同的缺省字符串的查询将被认为是不同的查询 并将分别的缓冲 高速缓冲不对 SELECT CALC_ROWS … 和 SELECT FOUND_ROWS() … 类型的查询起作用 因为找到的行的数目也是被存储在缓冲里的 如果查询结果被从查询缓存中返回 那么状态变量 Com_select 将不会被增加 但是 Qcache_hits 却会增加 查看章节 查询缓存的状态和维护 如果一个表发生的改变 (INSERT UPDATE DELETE TRUNCATE ALTER 或 DROP TABLE|DATABASE) 那么所有这张表使用的缓冲的查询(可能通过一个 MRG_MyISAM 表!)将被得失效 并从缓冲中移除 InnoDB 表的事务所做的更改将在一个 MIT 被完成时 使数据失效 如果一个查询包括下面的函数 它将不能被缓冲 函数 函数 函数 User Defined Functions CONNECTION_ID FOUND_ROWS GET_LOCK RELEASE_LOCK LOAD_FILE MASTER_POS_WAIT NOW SYSDATE CURRENT_TIMESTAMP CURDATE CURRENT_DATE CURTIME CURRENT_TIME DATABASE ENCRYPT (只有一个参数调用) LAST_INSERT_ID RAND UNIX_TIMESTAMP (无参数调用) USER BENCHMARK 如果一个查询包含用户变量 引用 MySQL 系统数据库 或下列之一的格式 SELECT … IN SHARE MODE SELECT … INTO OUTFILE … SELECT … INTO DUMPFILE … 或 SELECT * FROM AUTOINCREMENT_FIELD IS NULL (检索最后一个插入 ID ODBC 语句) 该查询亦不可以被缓存 然而 FOUND ROWS() 将返回正确的值 即使先前的查询是从缓存中读取的 万一一个查询不使用任何表 或使用临时表 或用户对任何相关表有一个列权限 那么查询将不会被缓存 在一个查询从查询缓存中读取前 MySQL 将检查用户对所有相关的数据库和表有 SELECT 权限 如果不是这种情况 缓存的结果将不能被使用
查询缓存设置 查询缓存为了 mysqld 添加了几个 MySQL 系统变量 它可以在配置文件中被设置 或在启动 mysqld 时的命令行上设置 query_cache_limit 不缓存大于这个值的结果 (缺省为 M) query_cache_min_res_unit 这个变量从 被引进 查询的结果 (已被传送到客户端的数据) 在结果检索期间被存储到查询缓存中 因而 数据不会以一个大块地处理 查询缓存在需要时分配块用于处理这个数据 所以当一个块被填充后 一个新的块被分配 甚为内存分配操作是昂贵的 查询缓存以最小的尺寸 query_cache_min_res_unit 分配块 当一个查询执行完成 最后的结果块被修整到实际数据的尺寸大小 以便未使用的内存被释放 query_cache_min_res_unit 的缺省值为 KB 在大多数据情况下已够用了 如果你有许多查询返回一个较小的结果 缺省的块尺寸可能会引起内存碎片 (显示为一个很大数量的空闲块(Qcache_free_blocks) 这将引起查询缓存不得不因缺乏内存(Qcache_lowmem_prunes)而从缓存中删除查询) 在这种情况下 你应该减少 query_cache_min_res_unit 如果你的主要查询返回的是大的结果集(查看 Qcache_total_blocks 和 Qcache_queries_in_cache) 你可以通过增加 query_cache_min_res_unit 来增加性能 然而 要小心不要将它设得太大 query_cache_size 为了存储老的查询结果而分配的内存数量 (以字节指定) 如果设置它为 查询缓冲将被禁止(缺省值为 ) query_cache_type 这个可以被设置为 (只能是数字) 选项 含义 (OFF 不缓存或重新得到结果) (ON 缓存所有的结果 除了 SELECT SQL_NO_CACHE … 查询) (DEMAND 仅缓存 SELECT SQL_CACHE … 查询) 在一个线程(连接)内 查询缓存的行为可以被改变 句法如下所示 QUERY_CACHE_TYPE = OFF | ON | DEMAND QUERY_CACHE_TYPE = | | 选项 含义 or OFF 不缓存或重新得到结果 or ON 缓存所有的结果 除了 SELECT SQL_NO_CACHE … 查询 or DEMAND 仅缓存 SELECT SQL_CACHE … 查询 在 SELECT 中的查询缓存选项 有两个可能的查询缓存相关的参数可以在一个 SELECT 查询中被指定 选项 含义 SQL_CACHE 如果 QUERY_CACHE_TYPE 为 DEMAND 允许该查询被缓存 如果 QUERY_CACHE_TYPE 为 ON 这是缺省的 如果 QUERY_CACHE_TYPE 为 OFF 它不做任何事 SQL_NO_CACHE 使这个查询不被缓存 不允许这个查询被存储到高速缓存中 查询缓存的状态和维护 使用 FLUSH QUERY CACHE 命令 你可以整理查询缓存 以更好的利用它的内存 这个命令不会从缓存中移除任何查询 FLUSH TABLES 会转储清除查询缓存 RESET QUERY CACHE 使命从查询缓存中移除所有的查询结果 你可以检查查询缓存在你的 MySQL 是否被引进 mysql SHOW VARIABLES LIKE have_query_cache ; + + + | Variable_name | Value | + + + | have_query_cache | YES | + + + row in set ( sec) 在 SHOW STATUS 中 你可以监视查询缓存的性能 变量 含义 Qcache_queries_in_cache 在缓存中已注册的查询数目 Qcache_inserts 被加入到缓存中的查询数目 Qcache_hits 缓存采样数数目 Qcache_lowmem_prunes 因为缺少内存而被从缓存中删除的查询数目 Qcache_not_cached 没有被缓存的查询数目 (不能被缓存的 或由于 QUERY_CACHE_TYPE) Qcache_free_memory 查询缓存的空闲内存总数 Qcache_free_blocks 查询缓存中的空闲内存块的数目 Qcache_total_blocks 查询缓存中的块的总数目 Total number of queries = Qcache_inserts + Qcache_hits + Qcache_not_cached 查询缓存使用变长的块 因而 Qcache_total_blocks 和 Qcache_free_blocks 可能显示查询缓存的碎片 在 FLUSH QUERY CACHE 之后 只有剩余一个单独的(大的)空闲块 注意 每个查询最小需要两个块(一个用于存储查询文本 另一个或多个用于存储查询结果) 同样的 每个被一个查询使用的表需要一个块 但是 如果有两个或更多的查询使用同一张表 仅仅只需要分配一个块就行了 你可以使用状态变量 Qcache_lowmem_prunes 来谐调查询缓存尺寸 它计数被从缓存中移除的查询 该查询的移除是为了释放内存 以缓存新建的查询 查询缓存使用一个 least recently used (LRU) 策略来判断从缓存中移除哪个查询 lishixinzhi/Article/program/MySQL/201311/29499
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流