redis和mysql的結(jié)合示例

mysql和redis的區(qū)別

mysql是關(guān)系型數(shù)據(jù)庫,主要用于存放持久化數(shù)據(jù),將數(shù)據(jù)存儲在硬盤中,讀取速度較慢。

redis是非關(guān)系型數(shù)據(jù)庫,即將數(shù)據(jù)存儲在緩存中,緩存的讀取速度快,能夠大大的提高運行效率,但是保存時間有限

django中使用mysql的方法

通過繼承models.Model來生成數(shù)據(jù)庫表,詳情見Django模型的使用。

django中使用redis的方法

首先安裝python庫

pip3 install django-redis

在settings.py中增加如下代碼

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
        },
    },
}
REDIS_TIMEOUT=7*24*60*60
CUBES_REDIS_TIMEOUT=60*60
NEVER_REDIS_TIMEOUT=365*24*60*60

在業(yè)務(wù)邏輯代碼中加入

from django.core.cache import cache

此后,就可以通過

cache.set(key,value)

進行鍵值對的存儲。通過

cache.get(key)

進行鍵值對的查詢。

問題實例

在筆者實現(xiàn)的彈幕系統(tǒng)中,每一個發(fā)送到服務(wù)器的彈幕都要判斷其所對應(yīng)的活動是否接受圖片彈幕。是否接受圖片彈幕,原先存儲在mysql的活動表中。但是每次發(fā)送彈幕都要從mysql中查詢一次其所屬的活動會降低系統(tǒng)的性能,同時總活動數(shù)(相對于彈幕數(shù)量)較少,適合將其存到redis中。

由于mysql和redis中都會維護活動的相關(guān)信息,因此在增刪改查時需要保證數(shù)據(jù)的一致性。

考慮到請求的種類特點,此處采用了一種較為簡潔的策略:

  • 由于發(fā)送彈幕的請求數(shù)量較多,而每次發(fā)送彈幕是都需要查詢活動信息,因此活動信息直接從redis查詢得到。
  • 由于修改活動信息的請求數(shù)量較少,不妨每次修改活動信息時會同時修改redis和mysql中的活動信息,從而保證了數(shù)據(jù)的一致性。

具體代碼如下

def read_from_cache(attribute, id):
    '''
    從內(nèi)存中讀取數(shù)據(jù)庫字段
    :param attribute: 屬性名
    :param id: 數(shù)據(jù)庫記錄的id
    :return:
    '''
    key = attribute + '_' + str(id)
    value = cache.get(key)
    if value is None:
        data = None
    else:
        data = json.loads(value)
    return data


def write_to_cache(attribute, id, value):
    '''
    向內(nèi)存中寫入數(shù)據(jù)庫字段
    :param attribute: 屬性名
    :param id: 數(shù)據(jù)庫記錄id
    :param value: 寫入的值
    :return:
    '''
    key = str(attribute) + '_' + str(id)
    cache.set(key, json.dumps(value), settings.NEVER_REDIS_TIMEOUT)


def get_activity_attribute(activity_id, attribute_name):
    '''
    從內(nèi)存中讀取與活動相關(guān)的屬性
    :param activity_id: 活動id
    :param attribute_name: 屬性名
    :return: 返回值。如果沒有找到,返回None
    '''
    data = read_from_cache("activity_"+attribute_name, activity_id)
    if data is not None:  #如果能在內(nèi)存中查到
        print("在內(nèi)存中找到", "屬性名="+attribute_name, "id=",activity_id,"value=", data)
        return data  #則直接返回
    activities = Activity.objects.filter(id=activity_id)  # 否則在數(shù)據(jù)庫中進行查找
    if len(activities) == 0:
        return None
    try:
        data = activities.values(attribute_name)
        data = data[0][attribute_name]
        write_to_cache("activity_" + attribute_name, activity_id, data)
        return data
    except:
        return None


def set_activity_attribute(activity_id, attribute_name, value):
    '''
    向內(nèi)存中寫入與活動相關(guān)的信息
    :param activity_id: 活動id
    :param attribute_name: 屬性名
    :param value: 值
    :return: 是否設(shè)置成功
    '''
    activities = Activity.objects.filter(id=activity_id)  # 首先寫到數(shù)據(jù)庫中
    if len(activities) == 0:
        return False
    setattr(activities[0], attribute_name, value)
    activities[0].save()
    write_to_cache("activity_"+attribute_name, activity_id, value)  # 然后在內(nèi)存中更新相應(yīng)字段
    return True
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容