面试题答案
一键面试- 批量处理:
- 在Redis中,可以设置一个合适的阈值,例如每收集到100个库存更新请求,再批量从Redis队列中取出数据,一次性更新到MySQL。这样可以减少MySQL的更新次数,降低压力。
- 示例代码(以Python为例,使用
redis - py
库和pymysql
库):
import redis import pymysql r = redis.Redis(host='localhost', port=6379, db = 0) conn = pymysql.connect(host='localhost', user='user', password='password', database='test') cursor = conn.cursor() batch_size = 100 while True: batch = r.lrange('stock_update_queue', 0, batch_size - 1) if not batch: break update_sql = "UPDATE products SET stock = %s WHERE product_id = %s" data = [] for item in batch: product_id, stock = item.decode('utf - 8').split(',') data.append((stock, product_id)) cursor.executemany(update_sql, data) conn.commit() r.ltrim('stock_update_queue', batch_size, -1) conn.close()
- 使用Redis事务:
- Redis事务可以保证在事务执行期间,一系列操作要么全部成功,要么全部失败。对于库存更新请求,可以将相关操作放入一个Redis事务中,确保数据的一致性。
- 例如,假设库存更新请求包含商品ID和更新数量,首先从Redis中获取当前库存值,然后在事务中进行更新操作,最后将结果同步到MySQL。
- 示例代码(以Python为例,使用
redis - py
库):
import redis r = redis.Redis(host='localhost', port=6379, db = 0) product_id = '123' update_amount = 10 pipe = r.pipeline() current_stock = pipe.get(product_id) if current_stock is None: new_stock = update_amount else: new_stock = int(current_stock.decode('utf - 8'))+update_amount pipe.set(product_id, new_stock) pipe.execute() # 后续将新的库存值同步到MySQL
- 缓存库存数据:
- 将库存数据缓存在Redis中,对于频繁的库存查询请求,直接从Redis中获取数据,减少对MySQL的读压力。
- 当有库存更新请求时,先更新Redis中的库存数据,再异步更新MySQL。可以使用消息队列(如RabbitMQ、Kafka等)来异步处理MySQL的更新,确保数据最终一致性。
- 例如,在Python中使用
Flask
框架处理库存查询和更新:
from flask import Flask import redis app = Flask(__name__) r = redis.Redis(host='localhost', port=6379, db = 0) @app.route('/stock/<product_id>', methods=['GET']) def get_stock(product_id): stock = r.get(product_id) if stock is None: # 从MySQL获取库存并更新到Redis # 这里省略MySQL查询代码 stock = 100 r.set(product_id, stock) return str(stock) @app.route('/update_stock/<product_id>/<update_amount>', methods=['POST']) def update_stock(product_id, update_amount): current_stock = r.get(product_id) if current_stock is None: new_stock = int(update_amount) else: new_stock = int(current_stock.decode('utf - 8'))+int(update_amount) r.set(product_id, new_stock) # 将更新请求发送到消息队列,异步更新MySQL # 这里省略消息队列发送代码 return 'Stock updated successfully' if __name__ == '__main__': app.run(debug=True)
- 限流:
- 利用Redis的原子操作(如
INCR
)实现限流,限制单位时间内进入MySQL的库存更新请求数量。例如,设置每秒最多允许100个库存更新请求进入MySQL。 - 示例代码(以Python为例,使用
redis - py
库):
import redis import time r = redis.Redis(host='localhost', port=6379, db = 0) limit = 100 period = 1 # 秒 def is_allowed(): key = 'update_limit_key' current_count = r.incr(key) if current_count == 1: r.expire(key, period) return current_count <= limit while True: if is_allowed(): # 从Redis队列取出数据更新MySQL # 这里省略更新MySQL代码 pass else: time.sleep(0.01)
- 利用Redis的原子操作(如