
# Savepoints相关问题解决方案
1. 用户必须为job中的所有算子均分配ID吗？ 严格地说，用户只给有状态的算子分配IDs即可，因为在savepoint中仅包括有状态的算子的状态，没有状态的算子并不包含在savepoint中。
   在实际应用中，强烈建议用户给所有的算子均分配ID，因为有些Flink的内置算子，如window算子是有状态的。具体哪个算子是有状态的，哪个算子是无状态的，不是十分明显。如果用户十分确定某个算子是无状态的，该算子可以不调用uid()方法分配ID。
   
2. 如果用户在升级作业时新添加一个有状态的算子有什么影响？ 当用户在作业中新添加一个有状态的算子时，由于该算子是新添加的，无保存的旧状态，因此无状态恢复，从0开始运行。
   
3. 如果用户在升级作业时从作业中删除一个有状态的算子有什么影响？ 默认情况下，savepoint会尝试将所有保存的状态恢复。如果用户使用的savepoint中包含已经删除算子的状态，恢复将会失败。
   用户可以通过--allowNonRestoredState(简写为-n)参数跳过恢复已经删除的算子的状态：
   ```
   $ bin/flink run -s savepointPath -n [runArgs]
   ```
   
4. 如果用户重新编排有状态的算子的顺序有什么影响？
   - 如果用户已经给这些算子分配IDs，那么这些状态会正常恢复。
   
   - 如果用户没有给这些算子分配IDs， 这些算子将会按新的顺序自动分配新的ID，这将导致状态恢复失败。
    
5. 如果用户在作业中删除或添加或更改无状态算子的顺序有什么影响？
   - 如果用户已经给有状态的算子分配ID，那么无状态的算子并不会影响从savepoint进行状态恢复。
   
   - 如果用户没有分配IDs，有状态算子的IDs由于顺序变化可能会被分配新的IDs，这将导致状态恢复失败。
    
6. 如果用户在状态恢复时改变了算子的并发度会有什么影响？ 如果Flink版本高于1.2.0且不使用已经废弃的状态API，如checkpointed，用户可以从savepoint中进行状态恢复。否则，无法恢复。
   
 
