当前位置:首页 > 开发教程 > mysql教程 >

Shining Ray

时间:2013-04-24 23:59 来源:网络整理 作者:采集侠 收藏

标签归档: mysql MySQL 大量 unauthenticated user 今天公司数据库出现了停顿和阻塞的问题,检查数据库的时候发现,show processlist;可以看到大量: 1 2 3 4 5 6 不断有未验证的用户尝试登录却没有通过,有同学Google出来,发现是和域名解析有关系: 不管

标签归档:mysql MySQL 大量 unauthenticated user

今天公司数据库出现了停顿和阻塞的问题,检查数据库的时候发现,show processlist;可以看到大量:

1

2

3

4

5

6

不断有未验证的用户尝试登录却没有通过,有同学Google出来,发现是和域名解析有关系:

不管什么客户端连接上来,服务器端都会对客户端进行DNS反查,来获得客户端的域名或主机名。

很有可能是因为DNS服务器出了问题,才导致无法解析——虽然解析出来的结果应该是没有

同学通过在my.cnf中加入skip-name-resolve来禁止反向域名解析(或者在启动命令行中添加参数--skip-name-resolve。

这种方式也是推荐的MySQL优化方式之一。

但这种方式的缺点是,权限中的host不能再使用主机名,而要使用IP地址,所幸我们配置的是“%”,因此我比较倾向于使用另一种方式,就是在/etc/hosts文件中添加对应的host记录:

1

本条目发布于 2009年03月6日。属于 日记 分类,被贴了 dns、mysql 标签。作者是 ShiningRay Rails SQL Session Store优化版

问题根源

原始的ActiveRecord会话仓库很慢。对于低流量的网站而言没有什么问题,但是对于大一点的而言就慢了。首先,它的慢是因为ActiveRecord本身比较慢。虽然这是一个强大的ORM框架,但对于像会话管理这种简单的任务而言就是杀鸡用牛刀了。

还有其他的解决方案如cookie会话仓库(会话长度有限,不能在会话中存放敏感数据),memcached(无法持久化+难以实现高可用性方案)。

这就是为何要创建SqlSession仓库的原因。它直接操作mysql的数据库API,要比原始的AR会话仓库快很多。不过有时候它还是比较慢,因为:

解决方案

FastSessions Rails插件便是作为对于以上几个问题的解决方案而诞生的。

首先,我们从会话表中去掉了id字段,所以我们无须用到auto-increment锁。接下来为了让查找更快,我们使用了以下这些技术:不使用(session_id)作为查找索引,使用(CRC32(session_id), session_id)——双列键,可以帮助MySQL更快地找到会话记录因为键的基数更高(这样,mysql可以更快地找到记录而不用检查很多索引行)。我们测试过这种方法,在大会话表中显示了10-15%的性能提升。

最后,也是最强的优化是,对于空会话不创建数据库记录,同时如果数据没有在请求处理过程中没有更新过,则会话数据不会存回数据库。这个更改基本上可以减少50-90%的插入数量(根据应用程序的情况)。

那么,你肯定在想,用了这个插件之后会话究竟能快多少?这很难说。结果要看你是怎么操作会话的:如果你很少更改会话数据(如登录时储存用户id),那么可能会有90%的性能提升,但如果每次访问,你都要给用户会话写入些信息(比如最后一次访问时间last_visit_time),那么根据服务器的负载和会话表的大小,可能有5-15%的性能提升。

你只需要安装一个简单的插件,便可以自动实现上面这些更改。

我们解决了AUTO_INC锁的问题并去掉auto-increment键之后,又引入了一个新的问题,我在这里想说一下。这个问题是这样的。InnoDB会根据主键将所有数据分组。这意味着当我们使用自增长主键并向表插入记录时,会话记录会被组到一起,顺序地存储在磁盘上。然而如果使用比较随机的值(如一个随机会话id的crc32值)作为主键,那么每一个会话记录会被插入到属于它自己的不同的地方,那么会产生一些随机I/O,这对于I/O有限制的服务器不是很理想。所以,我们决定让用户自己选择在部署的时候使用何种主键,当你想在MySQL 5.1.22+上使用这个模块的话,可以设置

CGI::Session::ActiveRecordStore::FastSessions.use_auto_increment = true

这样在InnoDB中会连贯地插入数据。另一个情况当你的MySQL服务器的I/O有限制,不想因为随机主键而增加随机I/O,也可以这样设置。

如果你不想丢失使用AR会话插件创建的旧会话数据,你可以设置

CGI::Session::ActiveRecordStore::FastSessions.fallback_to_old_table = true

这样当某些session_id在新的会话表中找不到的时候,就会回去访问旧的会话表。旧会话表的名字可以使用CGI::Session::ActiveRecordStore::FastSessions.old_table_name 变量进行设置.

这个选项会使会话变慢所以我建议只要在升级到新会话表的时候才使用。在这种情况下,新的会话数据就会存入新表中,当到了会话超时期限的时候,就可以删除旧表了(我们用了两个月的期限,过了两个月之后,我们就可以删除旧表,并将此选项关闭。)。

安装

安装FastSessions插件十分简单,只需以下几个步骤:

  • 将该插件代码从我们的SVN库中安装到vendor/plugins目录中(可以使用./script/plugin install安装,或者piston import命令进行安装——看你喜欢)例如:

    $ piston import vendor/plugins/fast_sessions
  • 在config/environment.rb文件中启用ActiveRecord会话仓库:

    Rails::Initializer.run do |config|
    ......
    config.action_controller.session_store = :active_record_store
    ......
    end
  • 为新的会话表创建数据库迁移:

    $ ./script/generate fast_session_migration AddFastSessions
  • 如果需要,可以打开新创建的迁移脚本并更改表名table_name和插件use_auto_increment参数。
  • 运行数据库迁移:

    $ rake db:migrate
  • 启动应用程序并尝试进行一定会保存数据到会话的操作。然后检查fast_sessions会话表(如果你没有改名字的话)有没有这条记录。
  • 下载

    该插件的最新版本可以在它的项目网站或在 SVN仓库中找到。该插件由Alexey Kovyrin(Percona的MySQL性能专家)制作。开发由Scribd.com赞助。

    本条目发布于 2008年12月22日。属于 翻译、解决方案 分类,被贴了 mysql、rails、ruby、scalability、session 标签。作者是 ShiningRay 横向扩展(Facebook)

    原文:Scaling Out

    作者:Jason Sobel (notes)

    翻译:ShiningRay

    我于2007年四月加入了Facebook,在结束了几周的课程之后,我的经理Robert Johnson来找我。我们谈了很久,不过内容可以归结为:

    Bobby: “那么,Jason,我们要在2008年之前在弗吉尼亚开一个新的数据中心。你能去帮点忙吗?”
    Me: “呃…. 可以”
    Bobby: “很好!”


    mysql教程阅读排行

    最新文章