redis資料轉存mysql總結

2021-08-28 03:21:28 字數 4378 閱讀 4239

redis的最佳使用場景是快取,用來持久化資料儲存也是可以的,但既然有更適合於用作持久化資料儲存的資料庫,我們為什麼不用呢,做到物盡其用,發揮其最大優勢,所以redis中有的資料,也有必要在mysql中進行儲存。

思路:我們可以使用python語言來編寫乙個程式,連線redis資料庫,連線mysql資料庫,再從redis裡面讀出資料,將資料插入到mysql資料庫中,最後新建乙個shell檔案,在檔案裡面呼叫寫好的python程式即可。詳細操作步驟如下:

1. 導包

import json   # json是一種輕量級的資料交換格式,後續程式中會用到json.loads()將已編碼的json字串解碼為python物件,json.dumps()是將python物件編碼成json字串  

import redis

import pymysql

2. 定義主函式
def

main()

:# 指定redis資料庫

rediscli = redis.strictredis(host=

'ip『, port=port, password='password', db=0)

# 指定mysql資料庫

mysqlcli = pymysql.connect(host=

"localhost"

, port=

3306

, user=

"user"

, passwd=

"password"

, db=

"task"

, charset=

"utf8"

)# 指定unique_id為唯一索引

point_unique =

'alter table tb_stop_record add unique key(`unique_id`)'

mysqlcli.cursor(

).execute(point_unique)

# 設定lrange取值的起始值和終止值,步長,頁數初始值設為0

page_start =

0 step =

2 page_end = page_start + step

page_num =

0# 統計出頁數

while

true

: data = rediscli.lrange(

'acct_stop_record'

, start=page_start, end=page_end)

# 判斷獲取到的資料是否為空

if data:

page_start = page_end +

1 page_end = page_start + step

page_num +=

1# 如果獲取到的資料為空,則跳出迴圈

else

:break

# 重新設定lrange取值的起始值和終止值,步長,資料總數初始值設為0,實際插入的資料條數初始值為0

page_start =

0 step =

2 page_end = page_start + step

total =

0 count =

0for page in

range(0

, page_num)

: data_list = rediscli.lrange(

'acct_stop_record'

, start=page_start, end=page_end)

page_start = page_end +

1 page_end = page_start + step

params =

for data in data_list:

total +=

1 item = json.loads(data)

if item.get(

'session_id'):

([item.get(

'session_id'

), item.get(

'unique_id'

), item.get(

'member_name')]

))else

:continue

try:

# 使用cursor()方法獲取游標

cursor = mysqlcli.cursor(

) sql =

"insert ignore into tb_stop_record(session_id,unique_id,member_name) " \

"values(%s,%s,%s)"

# 新增的資料量

add_num = cursor.executemany(sql, params)

count = count + add_num

mysqlcli.commit(

)# 關閉游標

cursor.close(

)except pymysql.error as e:

mysqlcli.rollback(

)print

"insert error"

, e try

:# 根據實際插入的條數和每頁的條數,計算出頁數,用math.ceil()向上取整

if count %

(step +1)

==0: page_num = count /

(step +1)

else

: page_num = math.ceil(count /

(step +1)

)# 計算最後一頁實際插入的條數

if count %

int(page_num)==0

: last_page_data_num = step +

1else

: last_page_data_num = count %

int(step +1)

print

'there are {} datas'

.format

(total)

print

'actually add {} pages,insert {} datas,per page has {} datas,the last page insert {} datas.'

.format

(int

(page_num)

, count,step +

1, last_page_data_num)

except zerodivisionerror:

print

'there are {} datas'

.format

(total)

print

'the data already exists in the database'

"""

乙個python的檔案有兩種使用的方法,第一是直接作為指令碼執行,第二是import到其他的python指令碼中被呼叫(模組重用)執行。因此if __name__ == '__main__': 的作用就是控制這兩種情況執行**的過程,在if __name__ == '__main__': 下的**只有在第一種情況下(即檔案作為指令碼直接執行)才會被執行,而import到其他指令碼中是不會被執行的。

"""if __name__ ==

"__main__"

: main(

)

在終端命令列中輸入以下命令,建立乙個shell指令碼

vim redis_mysql_script.sh
#! /bin/bash

python filename.py

sh redis_mysql_script.sh
資料轉存成功。

這一過程看似挺簡單,實際上要注意的點不少,例如從redis資料庫中取出資料時如果用blpop或者lpop的話,會將原庫中的資料刪除,而一旦資料在mysql中沒插入成功,那麼我們的資料就丟失了。如果我們使用lrange方法來讀取資料,能保證資料的安全性。sql語句中佔位符也是乙個值得注意的地方,不管是什麼型別,統一用%s作為佔位符。還有redis讀取出的資料字段的個數和mysql表中的字段個數不相等的問題,也需要注意。還有效率問題,如果用for迴圈來遍歷這個列表,那麼在列表容量大的情況下,效率會很低,因此,需要用批量來讀取,批量插入mysql資料庫。還有要解決對重複資料插入的解決。

享受知識帶來的喜悅,保持鑽研的動力,繼續努力,穩健前行。

MySQL和Redis 資料同步解決方案總結

mysql和redis 資料同步解決方案總結 現在在中集e棧工作,最近在做乙個redis箱格資訊資料同步到資料庫mysql的功能。自己想了想,也有大概方案。1 佇列同步,變跟資料2份,使用訊息佇列,乙份給redis消費,乙份給mysql消費。2 後台定時任務,定時重新整理redis中箱格資訊到資料庫...

linux轉存mysql資料庫表和資料

命令列下具體用法如下 匯出資料庫表 mysqldump u使用者名稱 p密碼 d 資料庫名 表名 指令碼名 匯入sql檔案 mysql h30.1.32.181 p3306 u root proot epolicy 匯出整個資料庫結構和資料 mysqldump h localhost uroot p...

MySQL資料匯入Redis

從mysql中將資料匯入到 redis的 mysql 多個字段拼接 1.保證mysql有表 events all time 這個就是mysql要傳遞的資料表 create table events all time id int 11 unsigned not null auto increment...