5月 27

从mysql向redis中加载数据测试

  有测试显示reids如果使用持久化测试后效率会下降,所以不使用持久化。现在来测试一下从mysql中捞取数据加载到redis中的速度。
  服务器使用8核2.6 cpu,内存8G,sas硬盘,Centos5.6 64位操作系统。python 2.6 redis2.4.13.
  使用测试代码如下,从mysql的photo表中捞取两列数据加载到redis中,这两列在表中都有索引,数据量28万。

#!/bin/env python
# -------------------------------------------------
# Filename:    
# Revision:    
# Date:        2012-05-27
# Author:      simonzhang
# Email:       simon-zzm@163.com
# -------------------------------------------------
import MySQLdb
import redis


def redis_run(sql_data):
    try:
        r = redis.Redis(host='192.168.1.100', password = '123456', port=6379, db=0)
    except redis.RedisError, e:
        print "Error %s" % e
    for i in sql_data:
        r.set(str(i[0]),i[1])
        

def mysql_run(sql):
    try:
        db = MySQLdb.connect(host='192.168.1.100', user='test', passwd ='123456', db='photo')
        cursor = db.cursor()   
    except MySQLdb.Error, e:
        print "Error %d:%s" % (e.args[0],e.args[1])
        exit(1)
    try:
        result_set = ''
        cursor.execute('%s' % sql)
        result_set=cursor.fetchall()
        cursor.close()
        db.close()
        return  result_set
    except MySQLdb.Error, e:
        print "Error %d:%s" % (e.args[0], e.args[1])
        cursor.close()
        db.close()

def main():
    _loop = 0
    _limit_start = 0
    _limit_span = 10000
    _count_result = 5
    while _count_result > 0:
        result_data = ''
        sql = "select id as pid, userid as uid from photo LIMIT %s,%s" % (_limit_start + _limit_span * _loop, _limit_span)
        result_data = mysql_run(sql)
        _count_result = len(result_data)
        redis_run(result_data)
        _loop += 1


if __name__ == '__main__':
    main()

进行测试,分别为每次捞取50万,10万,5万,1万,结果如下:

50万
real 0m26.239s
user 0m16.816s
sys 0m5.745s

10万
real 0m24.019s
user 0m15.670s
sys 0m4.932s

5万
real 0m26.061s
user 0m15.789s
sys 0m4.674s

1万
real 0m28.705s
user 0m15.778s
sys 0m4.913s

结论:每次捞取10万效率会比较理想,对于操作系统的压力不大,所以硬件方面不用考虑。
这里两列保存的都是id,加入用户id和照片id长度都是9位,一组数据是18位。一亿组数据也就需要2G内存。
通过计算28万需要24秒,如果有1亿的数据,全部倒入要2个半小时。所以内存存储不是问题。不知道用固态硬盘是否能快,我没有就不知道了。所以要做三件事,一做好集群,将数据及时同步到其他机房,自己写个程序同步定时同步,如果用主从,主机重启了为空,这个就很麻烦了,二使用redis的数据持久化,肯定比从mysql中直接捞快,三天天烧香希望不要宕机。

5月 27

python连接oracle和mysql备忘

import cx_Oracle
    
def sql_comm(sql_run):
    db = cx_Oracle.connect(‘user’, ‘passwd’, ‘IP:port/sid’) 
    try:
        cursor=db.cursor()
    except cx_Oracle.ERROR,e:
        print “Error %d:%s”%(e.args[0],e.args[1])
    try:
           cursor.execute(sql_run)
    result_set=cursor.fetchall()
           cursor.close()
           db.commit()
           db.close()
    return result_set
    except e:
        print “Error %s”%(e.args[0])
        cursor.close()
        db.close()

python连接mysql

import MySQLdb

def sql_comm(sql_run):
        try:
                conn=MySQLdb.connect(host=host,user=username,passwd=pwd,db=database)
                cursor = conn.cursor()
        except MySQLdb.Error,e:
                print “Error %d:%s”%(e.args[0],e.args[1])
        try:
                cursor.execute(sql_run)
                result_set=cursor.fetchall()
                cursor.close()
                db.close()
                return result_set
        except MySQLdb.Error,e:
                print “Error %d:%s”%(e.args[0],e.args[1])
                cursor.close()
                db.close()

注意部分,在mysql修改数据时最好使用commit,如果只是select就不用了,不然得不到数据。
在oracle和mysql插入大量数据时,可以使用executemany,需要注意的是,oracle插入大量
数据时要将数据类型为元组,然后放到列表中。建议一次插入10000行。