美文网首页
redis和mysql的结合示例

redis和mysql的结合示例

作者: 江俊广 | 来源:发表于2018-12-14 23:07 被阅读0次

    mysql和redis的区别

    mysql是关系型数据库,主要用于存放持久化数据,将数据存储在硬盘中,读取速度较慢。

    redis是非关系型数据库,即将数据存储在缓存中,缓存的读取速度快,能够大大的提高运行效率,但是保存时间有限

    django中使用mysql的方法

    通过继承models.Model来生成数据库表,详情见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
    

    在业务逻辑代码中加入

    from django.core.cache import cache
    

    此后,就可以通过

    cache.set(key,value)
    

    进行键值对的存储。通过

    cache.get(key)
    

    进行键值对的查询。

    问题实例

    在笔者实现的弹幕系统中,每一个发送到服务器的弹幕都要判断其所对应的活动是否接受图片弹幕。是否接受图片弹幕,原先存储在mysql的活动表中。但是每次发送弹幕都要从mysql中查询一次其所属的活动会降低系统的性能,同时总活动数(相对于弹幕数量)较少,适合将其存到redis中。

    由于mysql和redis中都会维护活动的相关信息,因此在增删改查时需要保证数据的一致性。

    考虑到请求的种类特点,此处采用了一种较为简洁的策略:

    • 由于发送弹幕的请求数量较多,而每次发送弹幕是都需要查询活动信息,因此活动信息直接从redis查询得到。
    • 由于修改活动信息的请求数量较少,不妨每次修改活动信息时会同时修改redis和mysql中的活动信息,从而保证了数据的一致性。

    具体代码如下

    def read_from_cache(attribute, id):
        '''
        从内存中读取数据库字段
        :param attribute: 属性名
        :param id: 数据库记录的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):
        '''
        向内存中写入数据库字段
        :param attribute: 属性名
        :param id: 数据库记录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):
        '''
        从内存中读取与活动相关的属性
        :param activity_id: 活动id
        :param attribute_name: 属性名
        :return: 返回值。如果没有找到,返回None
        '''
        data = read_from_cache("activity_"+attribute_name, activity_id)
        if data is not None:  #如果能在内存中查到
            print("在内存中找到", "属性名="+attribute_name, "id=",activity_id,"value=", data)
            return data  #则直接返回
        activities = Activity.objects.filter(id=activity_id)  # 否则在数据库中进行查找
        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):
        '''
        向内存中写入与活动相关的信息
        :param activity_id: 活动id
        :param attribute_name: 属性名
        :param value: 值
        :return: 是否设置成功
        '''
        activities = Activity.objects.filter(id=activity_id)  # 首先写到数据库中
        if len(activities) == 0:
            return False
        setattr(activities[0], attribute_name, value)
        activities[0].save()
        write_to_cache("activity_"+attribute_name, activity_id, value)  # 然后在内存中更新相应字段
        return True
    

    相关文章

      网友评论

          本文标题:redis和mysql的结合示例

          本文链接:https://www.haomeiwen.com/subject/kownhqtx.html